Djaka Pradana Jaya Priambudi
10/02/2022, 8:40 PMmolecule
library and migrating my presenter code into composable
function. But some function that have primitives parameter recomposed multiple times when it doesn't need to be.
code in thread
I expect presentCountryListState
to be recomposed everytime either initialState
is changed or query
is changed. This is true, it will always recompose when query changed but when I look at the console everytime query changed this log shows:
Recomposition for presentCountryListState
Recomposition for present
Recomposition for presentCountryListState
Recomposition for present
Notice that it run the function twice somehow
Anyone know why this is happening?Djaka Pradana Jaya Priambudi
10/02/2022, 8:42 PMval initialState by searchCountryUseCases.getSearchCountryCodeInitialState().rememberAndCollectAsState(listOf())
and the recomposition still happens twiceDjaka Pradana Jaya Priambudi
10/03/2022, 8:56 AM@Composable
override fun present(event: Flow<Event>): State {
var searchBox by remember { mutableStateOf("") }
var selectedCountry by remember { mutableStateOf<CountryCodeModel?>(null) }
val countryListState = presentCountryListState(searchBox)
println("Recomposition for present")
CollectEffect(event) {
when (it) {
is Event.ItemClicked -> {
selectedCountry = it.item
saveRecentCountryUseCase(it.item.code)
searchBox = ""
}
is Event.SearchBoxChanged -> searchBox = it.query
}
}
return State(
searchBox = searchBox,
countryListState = countryListState,
selectedCountry = selectedCountry
)
}
@Composable
private fun presentCountryListState(query: String): State.CountryListState {
println("Recomposition for presentCountryListState")
val initialState by searchCountryUseCases.getSearchCountryCodeInitialState().rememberAndCollectAsState(listOf())
var result: State.CountryListState by remember { mutableStateOf(State.CountryListState.Loading) }
if (query.isEmpty()) {
result = if (initialState.isEmpty()) {
State.CountryListState.Loading
} else {
State.CountryListState.Success(initialState)
}
} else {
LaunchedEffect(query) {
result = State.CountryListState.Loading
result = filterCountry(query)
}
}
return result
}
Zach Klippenstein (he/him) [MOD]
10/04/2022, 10:45 AMDjaka Pradana Jaya Priambudi
10/04/2022, 1:15 PMquery.isEmpty
? Since there's no suspend function and changing to loading there, the recomposition also happened twiceZach Klippenstein (he/him) [MOD]
10/04/2022, 2:38 PMgetSearchCOuntryCodeInitialState
line?Zach Klippenstein (he/him) [MOD]
10/04/2022, 2:38 PMCollectEffect
look like?Djaka Pradana Jaya Priambudi
10/04/2022, 2:40 PMLaunchedEffect(event) {
event.collect {...}
}
Djaka Pradana Jaya Priambudi
10/04/2022, 2:42 PMfun CollectEvent(event: Flow<Event>, action: (Event) -> Unit) = LaunchedEffect(event) {
event.collect { action(it) }
}
Zach Klippenstein (he/him) [MOD]
10/04/2022, 2:49 PMaction
lambda in a recomposition it won’t be used by the collector. That implementation is so simple though I think wrapping it in a function actually obscures the code and makes it harder to read, I would just inline it. Anyway, I don’t think that has anything to do with your double recomposition.Zach Klippenstein (he/him) [MOD]
10/04/2022, 2:50 PMZach Klippenstein (he/him) [MOD]
10/04/2022, 2:52 PMpresent
or presentCountryListState
that should trigger immediate recomposition after the initial composition, but since both those functions return a non-Unit value, neither of them get their own recompose scope. Whatever’s calling present
might be doing something to trigger the recomposition.Djaka Pradana Jaya Priambudi
10/04/2022, 2:59 PMskippable composable
can simplify a rective code. Example above, i want to see wether the composable will be skipped if the query
value is the same. I can achieve similar impact with remember(query)
but I want to shorten the code. If double recomlosition happening, that mean I cannot use skippable composable for my advantage.
I'm a bit confused too, I'll create a sample code for you later. The one that calling present is just a simple composable function, I've made multiple approach to call present
one of them is using molecule which wrap it in independent composable scope and the double recomposition still happeningZach Klippenstein (he/him) [MOD]
10/04/2022, 3:22 PMDjaka Pradana Jaya Priambudi
10/05/2022, 12:41 PM