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 derivedStateOf
Florian
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