Search code examples
androidkotlinandroid-jetpack-composecomposable

How is compose able to do the recomposition when provided with non-state object


See this below code first

class WellnessViewModel : ViewModel() {

    private val _tasks = getWellnessTasks().toMutableStateList()
    val tasks: List<WellnessTask>
        get() = _tasks

Now im passing tasks to composeFunction and any changes in the _tasks (adding or removing item) cause the composeFunction to recompose. But how exactly is this thing working since I'm providing the non state object to that function this the code below.

@Composable
fun WellnessScreen(
    modifier: Modifier = Modifier,
    wellnessViewModel: WellnessViewModel = viewModel()
) {
    Column(
        modifier = modifier
    ) {
        StatefulCounter()
        WellnessTasksList(
            list = wellnessViewModel.tasks,
            onCloseTask = {
                wellnessViewModel.remove(it)
            },
            onCheckedTask = { task, checked ->
                wellnessViewModel.changeTaskChecked(task, checked)
            }
        )
    }
}

Why is this working and how, a simple explanation is needed for this.


Solution

  • But how exactly is this thing working since I'm providing the non state object to that function this the code below

    Because SnapshotStateList is exactly a StateObject, and addition, deletion or updating an item with new instance triggers recomposition.

    @Stable
    class SnapshotStateList<T> : MutableList<T>, StateObject 
    

    _tasks = getWellnessTasks().toMutableStateList() is a SnapshotStateList. Any modification on that list, update requires new item to be set with if you wish to change properties, triggers recomposition since it's a StateObject. T hat's the thing with SnapshotStateList it triggers recomposition for the items that changed. You can consider it like a mutableStateOf(list) but with selective recomposition instead passing a new list that recomposes every item.

    Also when a lambda is not stable invoking it causes recomposition.

    Why does a composable recompose while seemingly being stateless (the only passed parameter is a function, not a state)

    Also you can check this answer out how to optimize recomposition using SnapshotStateList, unstable lambdas and passing stable inputs instead of List which is unstable.

    Jetpack Compose lazy column all items recomposes when a single item update