Jetpack Compose는 현대적인 안드로이드 UI 개발을 위한 선언적 UI 툴킷입니다. Compose에서는 UI 요소와 상태를 선언적으로 구성하고, 이들을 동적으로 갱신할 수 있도록 다양한 Effect 관련 함수들을 제공합니다. 이 글에서는 Compose에서 자주 사용되는 Effect() 함수들에 대해 구체적으로 설명하고, 각 함수가 어떤 역할을 하는지 예시와 함께 알아보겠습니다.
1. LaunchedEffect()
LaunchedEffect()는 컴포저블이 처음 실행되거나 상태가 변경될 때 실행되는 코드 블록을 정의할 수 있는 함수입니다. 주로 비동기 작업을 수행할 때 유용합니다.
사용 예시:
@Composable
fun LoadDataOnStart() {
val data = remember { mutableStateOf("") }
LaunchedEffect(Unit) {
// 예시로 2초 대기 후 데이터를 불러오는 비동기 작업
delay(2000)
data.value = "Data Loaded"
}
Text(text = data.value)
}
설명: LaunchedEffect는 컴포저블이 처음 실행될 때 혹은 키값이 변경될 때마다 실행됩니다. 위 예시에서는 컴포저블이 처음 실행될 때 비동기적으로 데이터를 로드하고, data 값을 갱신합니다.
2. rememberUpdatedState()
rememberUpdatedState()는 컴포저블에서 상태가 변경되었을 때 업데이트된 상태를 기억하게 해주는 함수입니다. 이 함수는 상태 변경 시 불필요한 재구성을 방지하고, 최신 상태를 스냅샷으로 기억하게 도와줍니다.
사용 예시:
@Composable
fun Timer(count: Int) {
val currentCount by rememberUpdatedState(count)
LaunchedEffect(currentCount) {
delay(1000)
Log.d("Timer", "Current count: $currentCount")
}
Text("Count: $currentCount")
}
설명: rememberUpdatedState()는 count 값이 변경될 때마다 해당 값을 최신 상태로 기억합니다. 이로써 LaunchedEffect()가 실행될 때마다 최신 상태를 사용할 수 있습니다.
3. SideEffect()
SideEffect()는 UI의 상태가 변경될 때 **부수 효과(side effect)**를 발생시키는 함수입니다. 예를 들어, UI 상태에 따라 로그를 기록하거나 외부 시스템에 데이터를 전송하는 작업을 할 때 사용됩니다.
사용 예시:
@Composable
fun TrackChanges(counter: Int) {
SideEffect {
// 상태가 변경될 때마다 로그 기록
Log.d("Counter", "Counter updated: $counter")
}
Text("Counter: $counter")
}
설명: SideEffect()는 컴포저블의 상태가 변경될 때마다 실행되며, UI 변경과는 독립적으로 동작합니다. 이 예시에서는 counter 값이 변경될 때마다 로그를 출력합니다.
4. DisposableEffect()
DisposableEffect()는 컴포저블이 사라질 때 정리 작업을 할 수 있도록 도와주는 함수입니다. 예를 들어, 리소스를 해제하거나 비동기 작업을 취소할 때 유용합니다.
사용 예시:
@Composable
fun NetworkCall() {
val scope = rememberCoroutineScope()
DisposableEffect(Unit) {
// 네트워크 요청을 시작하고
val job = scope.launch {
// 네트워크 요청 코드
}
// 컴포저블이 사라질 때 요청 취소
onDispose {
job.cancel()
}
}
Text("Network call in progress")
}
설명: DisposableEffect()는 컴포저블이 사라지거나 관련 리소스를 해제할 때 실행됩니다. 위 코드에서는 네트워크 호출을 시작하고, 컴포저블이 종료될 때 해당 작업을 취소합니다.
5. EffectOf()
EffectOf()는 Compose에서 의존성이 변경될 때 특정 코드가 실행되도록 하는 함수입니다. 주로 UI와 비즈니스 로직을 분리하고, 비동기 작업을 관리할 때 유용합니다.
사용 예시:
@Composable
fun FetchDataEffect(url: String) {
val response = remember { mutableStateOf("") }
EffectOf(url) {
// url이 변경될 때마다 데이터를 새로 로드
response.value = fetchDataFromUrl(url)
}
Text("Fetched Data: ${response.value}")
}
설명: EffectOf()는 url이 변경될 때마다 새로운 데이터를 로드하는 작업을 실행합니다. 이때, EffectOf는 주어진 의존성(url)이 변경될 때마다 실행됩니다.
6. Effect() 함수 사용 시 고려 사항
- 컴포저블 성능 최적화: 각 Effect() 함수는 상태 변경에 따라 다시 실행되므로, 불필요한 재구성을 방지하기 위해 적절한 의존성 관리가 중요합니다.
- 상태 관리와의 결합: Effect() 함수는 상태 변화와 밀접하게 연결되어 있기 때문에, 상태를 구체적으로 추적하고 관리하는 것이 좋습니다.
- 비동기 작업: Compose에서 Effect() 함수는 비동기 작업에 매우 유용합니다. 이를 통해 UI가 차단되지 않고, 비동기 작업이 끝날 때 UI를 갱신할 수 있습니다.
결론
Jetpack Compose에서 제공하는 다양한 Effect() 함수는 UI 상태 변경에 따른 부수 효과를 관리하거나 비동기 작업을 처리할 때 유용합니다. LaunchedEffect(), rememberUpdatedState(), SideEffect(), DisposableEffect() 등 각 함수는 특정 상황에 맞춰 사용되며, 컴포저블의 동작을 효율적으로 제어할 수 있게 해줍니다.