I'm having a problem that the mutable state ignores first value if set two values in a row. I assume it's expected behaviour, just wondering if there is a clean workaround for that? I have this code:
var userState by mutableStateOf<UserData?>(null)
fun clearState() {
userState = null // clear user state
cleanInnerState()
// Set next user state if exist
stateQueue.poll()?.let {
userState = it
}
}
@Composable
fun ProfileScreen() {
val userData = store.userState
if(userData == null){
clearViewModelState()
}
else {
UserUI(userData)
}
}
The problem that when we set the state value to null and then we set new state in a row it ignores the null value and observers the last set value only.
CodePudding user response:
In general, Compose will not recompose if the value in State is not changed. What I also noticed is that you keep using Imperative approach. Compose propagated another approach. I can tell it from
if(userData == null){
clearViewModelState()
}
This is not how it suppose to work because you just set view when the value is null. You will never know when the Composable function is to be invoked and on which thread. Please have a look at https://developer.android.com/jetpack/compose/mental-model for more info
CodePudding user response:
Recomposition starts whenever Compose thinks that the parameters of a composable might have changed. Recomposition is optimistic, which means Compose expects to finish recomposition before the parameters change again. If a parameter does change before recomposition finishes, Compose might cancel the recomposition and restart it with the new parameter.
When recomposition is canceled, Compose discards the UI tree from the recomposition. If you have any side-effects that depend on the UI being displayed, the side-effect will be applied even if composition is canceled. This can lead to inconsistent app state.
Ensure that all composable functions and lambdas are idempotent and side-effect free to handle optimistic recomposition.