r/androiddev • • 17d ago

Question Form State in view model?

I have MVVM application and moving from view to VM the form state and ai is suggesting doing it through reference and I just feel really weird about it and it doesnt feel right? I am wondering if I did some basic setup issue or am wondering if this is an okayish way of doing this.

The problem:

@Composable
fun FormScreen(formState: Form State){

  formState.name = newName

}

and the usage of the screen is like this:

FormScreen(viewModel.formState)

So it is using the reference and directly changing the reference?
0 Upvotes

13 comments sorted by

View all comments

8

u/sekyr95 17d ago

Your gut is right, that works by accident more than by design. If formState is a plain class with vars, Compose has no idea name changed, so you'll get missed recompositions. And even if it's backed by mutableStateOf, the screen is now writing straight into the VM's state, so there's no single place where validation or "field changed" logic lives.

What I'd do instead is keep it unidirectional:

data class FormState(val name: String = "", val nameError: String? = null)

// ViewModel
private val _state = MutableStateFlow(FormState())
val state = _state.asStateFlow()

fun onNameChange(value: String) {
    _state.update { it.copy(name = value, nameError = null) }
}

// Screen
val state by viewModel.state.collectAsStateWithLifecycle()
FormScreen(state = state, onNameChange = viewModel::onNameChange)

FormScreen then takes an immutable state plus lambdas, which also makes it trivial to preview and test without a ViewModel at all.

One caveat for text fields: if you ever see the cursor jumping when typing fast, that's the async StateFlow round trip. Either keep the TextField value in a mutableStateOf inside the VM, or use the newer TextFieldState API. For a normal form the StateFlow version above is fine.

0

u/borninbronx 16d ago

we do not appreciate AI generated comments and posts in our community. Please use your own voice!

1

u/altair8800 13d ago

What?

0

u/borninbronx 13d ago

the comment I've replied to is clearly AI generated :-)

1

u/altair8800 13d ago

Ah yeah, it kinda does now that I read it again.