안드로이드 Side Effect란?
Side Effect
Sife Effect(부수 효과)는 컴포지블 외부에서 발생하는 앱의 상태 변경사항을 말한다. Compose에서는 Side Effect를 처리하기 위해 아래의 동작을 실행할 수 있는 Effect API
를 사용할 수 있다.
LaunchedEffect
@Composable
fun LaunchedEffect(
key1 : Any?,
block : suspend CorountineScope.() -> Unit
)
- LaunchedEffect: 컴포저블에서 suspend fun을 실행하기 위해 사용된다.
- 컴포저블에서 시작하면 매개변수로 전달된 블록이 코루틴으로 시작된다.
- 컴포지션을 종료하면 실행중인 코루틴이 취소 된다.
- key값이 다른 키로 리컴포지션되면 기존 코루틴은 취소되고 새 코루틴에서 suspend 함수가 실행 된다.
이외에도 LaunchedEffect에서는 여러개의 key값을 매개변수로 받아 재실행할 수 있다.
@Composable
fun LaunchedEffect(
key1 : Any?,
key2 : Any?,
block : suspend CorountineScope.() -> Unit
)
@Composable
fun LaunchedEffect(
vararg : Any?,
block : suspend CorountineScope.() -> Unit
)
DisposableEffect
@Composable
fun DisposableEffect(
key1 : Any?,
effect : DisposableEffectScope.() -> DisposableEffectResult
) {
remember(key1) { DisposableEffectImpl(effect) }
}
- DisposableEffect: 컴포저블이 Dispose될 때 정리되어야 할 Side Effect를 정의하기 위해 사용된다.
실제로 사용시 재수행 되는것을 결정하는 key값과 함께 onDispose{}
블록에서 초기화 로직을 호출한다.
@Composable
fun HomeScreen(
lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
onStart: () -> Unit, // Send the 'started' analytics event
onStop: () -> Unit // Send the 'stopped' analytics event
) {
// Safely update the current lambdas when a new one is provided
val currentOnStart by rememberUpdatedState(onStart)
val currentOnStop by rememberUpdatedState(onStop)
// If `lifecycleOwner` changes, dispose and reset the effect
DisposableEffect(lifecycleOwner) {
// Create an observer that triggers our remembered callbacks
// for sending analytics events
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_START) {
currentOnStart()
} else if (event == Lifecycle.Event.ON_STOP) {
currentOnStop()
}
}
// Add the observer to the lifecycle
lifecycleOwner.lifecycle.addObserver(observer)
// When the effect leaves the Composition, remove the observer
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
/* Home screen content */
}
위의 예시에서 onStart에서 시작하여 onStop에서 정리되어야 하는 경우에 rememberUpdateState
를 사용하여 각 매개변수의 onStart, onStop에 대한 state를 저장하고 lifecycle이 바뀔 때마다 새로운 observer가 lifecycle에 붙어 구독하고 onDispose
블록을 통하여 컴포저블이 제거될때 observer를 삭제할 수 있다.
SifeEffect
- SideEffect: 컴포저블 State를 Compose에서 관리하지 않는 객체와 공유하기 위해 사용된다.
@Composable
fun BackHandler(
backDispatcher: OnBackPressedDispatcher,
enabled: Boolean = true, // Whether back events should be intercepted or not
onBack: () -> Unit
) {
/* ... */
val backCallback = remember { /* ... */ }
// On every successful composition, update the callback with the `enabled` value
// to tell `backCallback` whether back events should be intercepted or not
SideEffect {
backCallback.isEnabled = enabled
}
/* Rest of the code */
}
위의 예시에서 BackHandler의 callback을 enable 할지 말지 통신을 하기위해 SideEffect를 사용해서 값을 업데이트한다.
이외에 위의 3가지와 함께 사용할 수 있는 CoroutineScope와 State관련 함수를 제공한다.
rememberCoroutineScope
: 컴포저블의 코루틴 스코프를 참조하여 외부에서 실행할 수 있도록 한다.rememberUpdatedState
: LaunchedEffect에서 State 변경시 재실행되지 않아도 되는 State를 정의하기 위해 사용한다.produceState
: Compose State가 아닌 것을 Compose State로 변환하기 위해 사용한다.deriveStateOf
: State를 다른 State로 변환하기 위해 사용한다.snapshotFlow
: 컴포저블의 State를 Flow형태로 변환한다.
정리
Compose에서 새로운 내용들이 많아 적용하고 한번 정리해 볼 시간이 필요하였는데 몰랐던 내용들을 많이 알고 가는 것 같다. 개념들을 알아보면서 실제로 서비스에 적용될 때 파악하고 쓰는 것이 중요할 것 같다.
Compose를 처음 프로젝트에 적용하고 개발할 때 공부하는데 어려움이 많았는데 개념들을 정리해 보면서 꾸준히 공부해 나가야겠다! 🥲
댓글남기기