gpaligot
02/13/2022, 8:17 PMExampleUiState
) as single source of truth for the UI and because you can’t pass a state as parameter inside a Composable (otherwise, lint error), does that means I’m forced to redraw my entire screen at each change of my state?
Thanks in advance for your time! :)Adam Powell
02/13/2022, 8:28 PMmutableStateOf
is no more linked to composition and UI than using suspendCancellableContinuation
is linked to flows. For 2) this situation isn't any different from using val uiState by viewModel.uiStateFlow.collectAsState()
at the same point, do you have some code to share that you're concerned about?gpaligot
02/14/2022, 2:28 PMcollectAsState()
and get the full model which force the recomposition of the screen (maybe there is a performance issue with this function?) but if you are using mutableStateOf
inside your ViewModel, you get a state and you will force the recomposition only when you will call state.value
property.
It seems interesting to pass state as parameter to our composable functions to apply a recomposition to a subset of composables rather than the entire screen.Adam Powell
02/14/2022, 3:18 PMval uiState by myViewModel.uiState.collectAsState()
SomeComposable(uiState)
and
class MyViewModel : ViewModel() {
var uiState by mutableStateOf(UiState.Initial)
private set
}
// ...
SomeComposable(myViewModel.uiState)
as identical. They both invalidate when determining the parameter values to pass.uiState
in different places;
MyScaffold(
titleBar = { AppBar(..., uiState.title) },
itemContent = { Item(uiState.items[it]) },
)
etc. It might not be abstracted in a composable this way, instead this might just be the result of placing different things in a combination of rows, columns, cards, and your other custom containers in a single composable function. You might combine different parts of uiState
for some things, and each combined piece might change in its own way over time as well.[Mutable]State<T>
as the type of a parameter or public class property. This is an implementation detail, not API contract. If you want to afford deeper invalidation, use a lambda instead as it affords better flexibility for the caller:
// Don't
@Composable
fun FancyItem(state: State<SomeData>) {
SomeDeeplyNestedThing {
Text(state.value.text)
}
}
Instead do this:
// Do
@Composable
fun FancyItem(getState: () -> SomeData) {
SomeDeeplyNestedThing {
Text(getState().text)
}
}
gpaligot
02/14/2022, 4:08 PMStylianos Gakis
03/06/2022, 6:36 PM