I have a form screen written in Compose where the user can fill out some TextField
s and submit it. If they press the submit button before filling out the fields, the supporting text for the empty TextField
s will change to say "Required".
To do this, I've created a ViewState
that includes a showRequired
field:
data class ViewState(
showRequired: Boolean = false,
// other fields
)
In my view model, I create a MutableStateFlow
with the ViewState
as its default value:
private val _viewState: MutableStateFlow<ViewState> = MutableStateFlow(ViewState())
val viewState: StateFlow<viewState> = _viewState.asStateFlow()
To have the composable show the required message, I update the view state like this:
fun onSubmitClicked(form: Form) {
if (areRequiredFieldsMissing(form)) {
_viewState.update { it.copy(showRequired = true) }
}
}
In my composable, I'm collecting that flow with collectAsStateWithLifecycle()
and then checking if showRequired = true
before showing the message:
val viewState = viewModel.viewState.collectAsStateWithLifecycle()
if (viewState.value.showRequired) {
// set supportingText = Required
}
When I click the submit button, the message shows as expected. However, if I leave this screen and then come back to it, the required message shows by default instead of being hidden. I thought I could fix this by updating the view state when the back button is pressed to set showRequired = false
:
// in my view model
fun onBackPressed() {
_viewState.update { it.copy(showRequired = false) }
}
However this doesn't fix anything. When I come back to the form screen, the required message still shows by default. When I debug the composable, the value collected for showRequired
is still true. Why doesn't updating it to false work correctly, but updating it to true when clicking the submit button does? I think I'm misunderstanding how StateFlow
works but I'm not sure what to try.
EDIT: I resolved this by resetting my ViewState
when exiting the screen so that showRequired
is reset to false, instead of just updating it.
_viewState.value = ViewState()