Challenge 3: Collecting UiState in a Composable — Solution @Composable fun TodoScreen(viewModel: TodoViewModel = viewModel()) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() Column(modifier = Modifier.padding(16.dp)) { if (uiState.isLoading) { Text(text = "Loading...") } else { uiState.items.forEach { item -> Text(text = item) } } Spacer(modifier = Modifier.height(12.dp)) Button(onClick = { viewModel.addItem("New task ${uiState.items.size + 1}") }) { Text("Add Item") } } } Notes: - val uiState by viewModel.uiState.collectAsStateWithLifecycle() collects the WHOLE TodoUiState object as a single piece of Compose state — both uiState.isLoading and uiState.items come from that one collected value, never out of sync with each other. - The if (uiState.isLoading) / else branch renders completely different content depending on the state's isLoading flag — this is the payoff of the single-UiState-per-screen pattern from the chapter: one clean branch, rather than juggling several independent booleans and lists that could theoretically disagree with each other. - uiState.items.forEach { item -> Text(text = item) } uses Kotlin Fundamentals Chapter 6's forEach to render one Text per item — since addItem() replaces the whole TodoUiState (Challenge 2), tapping the button triggers recomposition and the new item appears in the list automatically.