I am still new to compose and I am curious how people treat this kind of thing. Let's imagine that we have a screen that has two variants, one variant with some views, another variant with other views. That variant should be dictated by a persisted flag, which I have stored using DataStore (the new SharedPrefs). The only issues is that unlike SharedPrefs, DataStore is asynchronous and is made to work with coroutines. So here's what happens, the screen gets rendered in default state (variant A) for just a split second, atfer about 100-200ms the viewModel successfully reads the value from DataStore on a coroutine and posts it on a mutableStateOf(), which as a result triggers recomposition with the variant B of the screen that is saved in the prefs. This transition is visible and the entire behavior looks glitchy. How do you fix this? I don't want the screen to compose the default state before the viewModel has time to read the stored value, I want the screen to await those 100-200ms without doing anything and composing the views only after the reading from DataStore.
The code looks like:
@Composable
fun MyScreen(){
val viewModel = hiltViewModel<ScreenViewModel>()
val state = viewModel.uiState
if(state == MyScreenState.A){
[...] // some view here
} else {
[...] // other view here
}
}
@HiltViewModel
class ScreenViewModel @Inject constructor(
private val dataStoreService: DataStoreService
) : BaseViewModel() {
var uiState by mutableStateOf(MyScreenState.A)
init {
viewModelScope.launch {
dataStoreService.flag().collect { flag ->
uiState = if(flag) MyScreenState.A else MyScreenState.B
}
}
}
}
For simplicity, MyScreenState is just a simple enum in this case. One of the things I thought about is defaulting the uiState to null instead of variant A and in my screen check if the state is null and if so returning a Unit (basically rendering nothing). If the state is not null, render the screen accordingly. But the truth is that I don't feel like making that uiState nullable, I avoid working with nulls at all cost because they make the code just a little less readable and needs extra handling. What's your solution on this? Thanks.