Decoupling the Compose-based UI layer from ViewModel
Our UI layer (represented by the composable functions) is tightly coupled to the ViewModel. This is natural, since the screen composables instantiate their own ViewModel to do the following:
- Obtain the UI state and consume it
- Pass events (such as clicking on a UI item) up to the
ViewModel
As an example, we can see how the RestaurantsScreen() composable uses an instance of RestaurantsViewModel:
@Composable
fun RestaurantsScreen(onItemClick: (id: Int) -> Unit) {
val viewModel: RestaurantsViewModel = viewModel()
val state = viewModel.state.value
Box(…) { … }
}
The problem with our approach is that if we want to later test the UI layer, then, inside the test, the RestaurantsScreen composable will instantiate RestaurantsViewModel, which in turn will get data from Use Case classes, which in turn will trigger heavy I/O work...