I have a Jetpack Compose (desktop) app with a database, and I want to show some UI based on data from the db:
val data = remember { mutableStateListOf<Dto>() }
Column {
data.forEach { /* make UI */ }
}
My question is, at which point should I execute my database query to fill the list?
I could do
val data = remember { mutableStateListOf<Dto>() }
if (data.isEmpty()) data.addAll(database.queryDtos())
The isEmpty
check is needed to prevent requerying on re-compose, so this is obviously not the way to go.
Another option would be
val data = remember {
val state = mutableStateListOf<Dto>()
state.addAll(database.queryDtos())
state
}
This way I can't reuse a database connection, since it's scoped inside the remember block. And queries should probably happen async, not inside this initializer
So, how to do this nicely?
CodePudding user response:
In Android the cleanest way is using view model, and call such code in init
.
In Desktop it depends on the operation. The main benefit of this platform is that there's no such thing as Android configuration change, so remember
/LaunchedEffect
are not gonna be re-created.
If the initialization code is not heavy, you can run it right inside
remember
.val data = remember { database.queryDtos() }
In case you need to update the list later, add
.toMutableStateList()
If it's something heavy, it's better to go for
LaunchedEffect
. It will have the same lifecycle asremember
- run the containing code only the first time the view appears:val data = remember { mutableStateListOf<Dto>() } LaunchedEffect(Unit) { data.addAll(database.queryDtos()) }