Side Effect(부수 효과 또는 부작용)란 Composable 범위 밖에서 발생하는 앱 상태에 대한 변경이다.
Side Effect를 이해하기 위해서는 아래 두가지를 이해해야 한다.
우리는 Composable을 사용할 때 여러 Composable들을 겹쳐서 사용한다. 그러면 시스템은 각 Composable에 대한 Lifecycle을 만들고, Composable 별로 재구성이 필요할 때만 재구성시킨다. 또한 Composable은 기본적으로 바깥쪽 Composable이 안쪽 Composable로 State를 내려준다. 이로 인해 단방향으로만 의존성이 생긴다. 하지만 만약 안쪽에 있는 Composable에서 바깥쪽에 있는 Composable의 상태에 대한 변경을 준다면? 혹은 Composable에서 Composable이 아닌 앱 상태에 대한 변화를 준다면? 양방향 의존성으로 인해 예측할 수 없는 Effect(효과)가 생길 것이다. 우리는 이를 Side Effect라 부른다.
Compose의 State을 Compose에서 관리하지 않는 객체와 공유하기 위해 사용한다. 이 함수는 recompose 마다 호출되므로 효율적인 사용을 위해서 특정 시점에만 실행되어야 하는 경우에는 LaunchedEffect를 필요에 따라 자원 해제가 필요한 경우에는 DisposableEffect로 대체할 수 있다.
Composable 내부에서 코루틴을 수행할 경우 Composable에 대한 Recomposition이 일어날 때 정리되어야 하는 코루틴이 정리가 안된 상태로 계속해서 코루틴이 쌓일 수 있다. Recomposition은 자주 일어나는 동작이므로 Recomposition마다 코루틴을 생성하는 것은 위험하여 심할 경우 앱 크래쉬가 생길수도 있다.
그래서 Composable에서 Coroutine을 생성한다면 Recomposition이 일어날 때 취소되어야 한다.(물론 예외도 있지만 대부분 Recomposition 일어날 때 취소해야 하는 경우가 대다수 이다.) Compose는 이를 위해 Composable의 Lifecycle을 따르는 CoroutineScope를 반환하는 remeberCoroutineScope() 함수를 제공 한다
openDrawer
콜백).@Composable
fun AppScreen(scaffoldState: ScaffoldState = rememberScaffoldState()) {
val scope = rememberCoroutineScope()
Scaffold(scaffoldState = scaffoldState) {
Column {
/* ... */
Button(
onClick = {
scope.launch {
scaffoldState.snackbarHostState
.showSnackbar("Something happened!")
}
}
) {
Text("Press me")
}
}
}
}