I have an MVI architecture with and activity containing the main screen
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyTheme {
val viewModel: MainScreenViewModel = viewModel(factory = MainScreenViewModel.Factory)
val state by viewModel.viewState.collectAsState()
MainScreen(state, viewModel::handleEvent)
}
}
}
}
The main screen looks somewhat like this:
@Composable
fun MainScreen(state: MainScreenState, onEvent: (Event) -> Unit) {
TaskList(
tasks = state.items,
onEvent = onEvent,
)
}
@Composable
fun TaskList(tasks: List<TaskState>, onEvent: (Event) -> Unit) {
LazyColumn {
items(items = tasks, key = { it.id }) {
Task(state = it, onEvent = onEvent)
}
}
}
Now, if the ViewModel emits a new MainScreenState
where one TaskState
is changed, the TaskList
recomposes. This is expected, as a new list object is passed. But not only the changed Task
is recomposed, but every Task
composable in the list. The reason for this is not the TaskState
, it is stable.
What seems to cause the recomposition is the onEvent
callback. If I change onEvent = onEvent
to onEvent = { onEvent(it) }
in the MainScreen
, the problem is solved. But I do not understand why. Shouldn't method references be stable as-well? I have even checked the hashCode, it's always the same.