No re-evaluation of remember in Jetpack Compose

  Kiến thức lập trình

I need to control the visibility of “save” button on my “settings” screen:

val enableSaveButton = remember(
    modifiedUser,
    originalUser,
    changePasswordData,
    modifiedExtraSettingsData,
    originalExtraSettingsData,
) {
    val userModifications = if (isLoggedIn) {
        modifiedUser.value != originalUser.value
    } else {
        false
    }
    val passwordModifications = changePasswordData.value != ChangePasswordData.NULL_OBJECT
    val isPasswordDataConsistent = if (isLoggedIn && passwordModifications) {
        changePasswordData.value.isValidData()
    } else {
        true
    }
    val extraModifications = modifiedExtraSettingsData.value != originalExtraSettingsData.value
    (userModifications || extraModifications || passwordModifications) && isPasswordDataConsistent
}

My problem is that this remember block is not re-evaluated when changePasswordData mutable state changes. It does re-evaluate when modifiedExtraSettingsData changes, however.
I used breakpoints in the code to verify that changePasswordData is indeed changed and that change triggers re-composition of the respective Composables, but not re-evaluation of the above expression.
As far as I can tell, I use the same approach for changePasswordData and modifiedExtraSettings, yet get different behavior.

These are the declarations of the respective mutable states:

    private val originalUser = mutableStateOf(User.NULL_USER)
    private val modifiedUser = mutableStateOf(User.NULL_USER)

    private val changePasswordData = mutableStateOf(ChangePasswordData.NULL_OBJECT)

    private val originalExtraSettingsData = mutableStateOf(ExtraSettingsData.NULL_OBJECT)
    private val modifiedExtraSettingsData = mutableStateOf(ExtraSettingsData.NULL_OBJECT)

And that’s how I mutate changePasswordData and modifiedExtraSettings:

MyTextField(
    modifier = Modifier.fillMaxWidth(),
    text = changePasswordData.value.currentPassword,
    label = stringResource(id = R.string.settings_current_password),
    enabled = true,
    visualTransformation = PasswordVisualTransformation(),
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Next),
    onValueChanged = {
        changePasswordData.value = changePasswordData.value.copy(
            currentPassword = it
        )
    }
)

MyTextField(
    modifier = Modifier.fillMaxWidth(0.5f),
    label = stringResource(id = R.string.settings_server_base_url_label),
    text = extraSettingsData.value.baseServerUrl,
    onValueChanged = {
        extraSettingsData.value = extraSettingsData.value.copy(
            baseServerUrl = it
        )
    }
)

So, why the difference in behavior?

LEAVE A COMMENT