Android/Compose

[Compose] Compose의 Side-Effect(2)

JunsuKim 2023. 5. 9.
728x90

Compose의 Side-Effect(1)

이전 내용에서 이어서 작성.

https://jjunsu.tistory.com/382

 

[Compose] Compose의 Side-Effect(1)

Compose의 부수 효과 부수 효과는 구성 가능한 함수의 범위 밖에서 발생하는 앱 상태에 관한 변경사항이다. 즉 자신이 아닌 외부의 상태에 영향을 만드는 것이다. 예측할 수 없는 리컴포지션 또는

jjunsu.tistory.com


DisposableEffect: 정리가 필요한 효과

키가 변경되거나 Composable을 종료한 후 정리가 필요할 때 DisposableEffect를 사용한다.

 

예를 들어, LifecycleObserver를 사용하여 Lifecycle 이벤트를 기반으로 애널리틱스 이벤트를 전송할 때 Compose에서 이러한 이벤트를 수신 대기하려면 DisposableEffect를 사용하여필요에 따라 관찰자를 등록 및 등록 취소한다.

@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 */
}

위 코드를 분석해보자.

Effect가 observer를 LifecycleOwner에 추가한다.

LifecycleOwner가 변경되면 Effect가 삭제되고 새로운 LifecycleOwner로 다시 시작된다.

 

DiposableEffect는 코드 블록의 마지막에 onDispose를 최종 문장으로 포함해 주어야 한다.

이를 포함시키지 않으면 IDE에 빌드 시간 오류가 표시되게 된다.

SideEffect: Compose State를 non-Compose 코드에 개시

Compose Effect를 Compose에서 관리하지 않는 객체와 공유하기 위해서는 recomposition 성공 시마다 호출되는

SideEffect Composable을 사용한다.

 

예를 들어, 애널리틱스 라이브러리를 사용하면 커스텀 메타데이터('사용자 속성' 등)를 이후의 모든 애널리틱스 이벤트에 연결하여 사용자 인구를 분류할 수 있다. 현재 사용자의 사용자 유형을 애널리틱스 라이브러리에 전달하려면 SideEffect를 사용하여 값을 업데이트한다.

@Composable
fun rememberAnalytics(user: User): FirebaseAnalytics {
    val analytics: FirebaseAnalytics = remember {
        /* ... */
    }

    // On every successful composition, update FirebaseAnalytics with
    // the userType from the current User, ensuring that future analytics
    // events have this metadata attached
    SideEffect {
        analytics.setUserProperty("userType", user.userType)
    }
    return analytics
}

produceState: non Compose State를 Compose State로 변환

Compose에서 관리하지 않는 객체와 Compose 상태를 공유하기 위해 모든 성공적인 재구성에서 호출되는 SideEffect 컴포저블을 사용한다.

예를 들어, 분석 라이브러리를 사용하면 사용자 정의 메타데이터를 모든 후속 분석 이벤트에 첨부하여 사용자 모집단을 세분화할 수 있다.

현재 사용자 유형을 분석 라이브러레이 전달하려면 SideEffect를 사용하여 해당 값을 업데이트 한다.

@Composable
fun loadNetworkImage(
    url: String,
    imageRepository: ImageRepository
): State<Result<Image>> {

    // Creates a State<T> with Result.Loading as initial value
    // If either `url` or `imageRepository` changes, the running producer
    // will cancel and will be re-launched with the new inputs.
    return produceState<Result<Image>>(initialValue = Result.Loading, url, imageRepository) {

        // In a coroutine, can make suspend calls
        val image = imageRepository.load(url)

        // Update State with either an Error or Success result.
        // This will trigger a recomposition where this State is read
        value = if (image == null) {
            Result.Error
        } else {
            Result.Success(image)
        }
    }
}

 

728x90

'Android > Compose' 카테고리의 다른 글

[Compose] @Preview 분석  (0) 2023.06.27
[Compose] Compose의 Side-Effect(3)  (0) 2023.05.15
[Compose] Compose의 Side-Effect(1)  (0) 2023.04.25
[Compose] Compose에서의 상태  (0) 2023.04.03
[Compose] Composable 재사용  (0) 2023.03.27

댓글