📌참고자료
@Composable
fun JetsnackApp(){
// place UI-element state in composable
val scaffoldState = rememberScaffoldState()
val coroutineScope = rememberCoroutineScope()
// all interactions with scaffoldState should happen in this composable
JetsnackScaffold(scaffoldState = scaffoldState){
Content(
//...
)
}
}
앱이 복잡해지면, seperation of concerns principle을 따라
delegate UI logic & UI state to different class(= State holder)
State holder
// State holder class
class JetsnackAppState(
val scaffoldState: ScaffoldState,
val navController: NavHostController,
//...
){
val shouldShowBottomBar: Boolean
@Composable get() = // read causes recompositions when value changes
navController.currentVackStackEntryAsState().value?.destination?.route in bottomBarRoutes
}
//...
}
@Composable
fun rememberJetsnackAppState(
scaffoldState: ScaffoldState = rememberScaffoldState(),
navController: NavHostController = rememberNavController(),
//...
) = remember(scaffoldState, navController, ...){
JetsnackAppState(scaffoldState, navController, ...)
}
class CartViewModel(
private val repository: SnackRepository,
private val savedState: SavedStateHandle
): ViewModel(){
fun increaseSnackCount(snackId: Long){ ... }
fun decreaseSnackCount(snackId: Long){ ... }
fun removeSnack(snackId: Long){ ... }
fun completeOrder(){ ... }
}
collectAsState
함수 사용해 Flow 사용class CartViewModel(
private val repository: SnackRepository,
private val savedState: SavedStateHandle
): ViewModel(){
val snacks: Flow<List<Snack>> = repository.snacks
//...
}
@Composable
fun Cart(viewModel: CartViewModel = viewModel()){
val snacks by viewModel.snacks.collectAsState()
//...
}