Mikolaj Leszczynski
12/02/2022, 9:53 PM4.5.0
to work around the issues inherent in Compose and to allow storing text state in ViewModels. This should fix https://github.com/orbit-mvi/orbit-mvi/issues/82
To do this, save text state in a blockingIntent
fun updateEmailInput(text: String) = blockingIntent {
reduce { state.copy(emailInput = text) }
}
Our testing so far showed this works, but we're keeping the DSL method opt-in for now.
Some tips:
1. Any work you do in a blockingIntent
blocks the UI thread. Do the bare minimum work necessary. Validation, filtering etc. should be OK, as even Google does that within Compose's onValueChange
in their examples.
2. If you need to do some work off the back of the text change e.g. launch a network request for search, you can do it off container.stateFlow
:
override val container: Container<State, Nothing> = scope.container(State()) {
onSearchTextChanges()
}
fun updateSearchText(text: String) = blockingIntent {
reduce { state.copy(query = text) }
}
private fun onSearchTextChanges() = intent {
container.stateFlow.map { it.query }
.distinctUntilChanged()
.debounce { if (it.isBlank()) 0 else 300 }
.collect { ... }
}
Note, this may prevent repeatOnSubscription
from working, as you have a permanent subscriber in the ViewModel
itself.