Stylianos Gakis
05/21/2024, 2:17 PMinterface GetSomething {
fun invoke(): Flow<SomeState>
}
If I got a @Composable annotated function which wants to grab this flow and start collecting it.
I can either remember it or not
class Presenter(private val getSomething: GetSomething) {
@Composable
fun comp(): UiState {
val state by getSomething.invoke().collectAsState(...)
// or
val state by remember(getSomething) { getSomething.invoke() }.collectAsState(...)
}
}
And if I understand correctly from testing this out, if I do not remember I definitely trigger invoke on each recomposition, but I also seem to re-start collection on each recomposition too. Since even though collectAsState
keys the flow itself, those two flows are not the same, do they do not ==
on the key check.
Looks like quite an easy pitfall to fall into no? Am I missing something?Zach Klippenstein (he/him) [MOD]
05/21/2024, 4:07 PMStylianos Gakis
05/21/2024, 4:19 PMZach Klippenstein (he/him) [MOD]
05/21/2024, 4:23 PMAlex Vanyo
05/21/2024, 4:26 PMFlow
operators outside of remember
Stylianos Gakis
05/21/2024, 5:19 PMremember
is the real solution, as long as I don't forget to do it. The lint check you mention Alex, I didn't get any such hints, is it perhaps some newer compose version, or does it not cover this use case for some reason? I don't recall ever seeing a lint check like that 👀Alex Vanyo
05/21/2024, 5:28 PMFlowOperatorInvokedInComposition
is the name of the lint rule, but it probably only detects some subset of operations.
There’s nothing specifically unique about Flow<SomeState>
- if you have any
interface GetSomething {
fun invoke(): MyType
}
and it’s important to not query invoke
more than once, then remember
is correct to cache it