Florian
08/15/2021, 6:44 PMderiveStateOf to calculate statisticsFoTask or is that not the correct approach?
@Composable
private fun TaskWithStatisticsList(
tasks: List<Task>,
taskStatistics: List<TaskStatistic>,
onTaskDetailsClicked: (Task) -> Unit,
modifier: Modifier = Modifier
) {
LazyColumn(
contentPadding = PaddingValues(bottom = 50.dp),
modifier = modifier
) {
items(tasks) { task ->
val statisticsForTask = taskStatistics.filter { it.taskId == task.id }
TaskWithStatisticsItem(
task = task,
statistics = statisticsForTask,
onTaskDetailsClicked = onTaskDetailsClicked
)
Divider()
}
}
}Dominaezzz
08/15/2021, 6:47 PMFlorian
08/15/2021, 6:50 PMFlorian
08/15/2021, 6:50 PMDominaezzz
08/15/2021, 6:53 PMZach Klippenstein (he/him) [MOD]
08/15/2021, 7:50 PMFlorian
08/15/2021, 8:19 PMderivedState do nothing here? I thought it would avoid filtering the list on every recomposition?Florian
08/15/2021, 8:20 PMremember together with derivedStateOfFlorian
08/15/2021, 8:20 PMFlorian
08/15/2021, 8:21 PMZach Klippenstein (he/him) [MOD]
08/15/2021, 9:26 PMFlorian
08/16/2021, 12:37 AMtasks list didn't change. And derivedStateOf avoids that the filter is executed again in those casesZach Klippenstein (he/him) [MOD]
08/16/2021, 12:51 AMderivedStateOf for that, you can just use remember:
val statisticsForTask = remember(task, taskStatistics) { taskStatistics.filter { it.taskId == task.id } }
That will ensure that the filter operation is only performed when either task or taskStatistics actually change.
Compare with:
val statisticsForTask = remember { taskStatistics.filter { it.taskId == task.id } }
This won’t work because there’s no keys to remember – the initial values of task and taskStatistics are captured the first time the remember is executed, and if it’s executed again with different values, the remembered result won’t get updated.
Or this:
val statisticsForTask by remember { derivedStateOf { taskStatistics.filter { it.taskId == task.id } }
This also won’t work for the same reason – because there’s no keys to remember, and because taskStatistics and task aren’t snapshot states, just regular values, if they change values the filter will not be recomputed.
To make this work with derivedStateOf, you’d need to either add keys to remember, in which case it’s exactly the same thing as my first example, but with extra overhead that’s not actually adding any value, or you’d need to use rememberUpdatedState to convert taskStatistics and task into snapshot state objects so that derivedStateOf can get change notifications. However, in that last case, because the only way those values can change is if your function is being re-executed, there’s absolutely no benefit to using `rememberUpdatedState`+`derivedStateOf` . Just the simple keyed remember is good enough.carbaj0
08/16/2021, 6:35 AMLaunchedEffect(task, taskStatistics) { ..} can be a good choice here, since filter can be a "heavy computation"Florian
08/16/2021, 10:35 AMFlorian
08/16/2021, 10:36 AMFlorian
08/16/2021, 10:38 AMZach Klippenstein (he/him) [MOD]
08/16/2021, 1:31 PMderivedStateOf doesn’t do anything interesting.Zach Klippenstein (he/him) [MOD]
08/16/2021, 1:36 PMFlorian
08/16/2021, 1:56 PMZach Klippenstein (he/him) [MOD]
08/16/2021, 2:32 PMZach Klippenstein (he/him) [MOD]
08/16/2021, 2:33 PMFlorian
08/16/2021, 2:44 PMFlorian
08/16/2021, 2:51 PMZach Klippenstein (he/him) [MOD]
08/16/2021, 3:27 PMFlorian
08/16/2021, 3:49 PM