
📌참고자료
@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()
    //...
}