면접 질문실전 질문꼬리 질문

compositionLocalOf vs staticCompositionLocalOf

skydovesJaewoong Eum (skydoves)||8분 소요

compositionLocalOf vs staticCompositionLocalOf

Jetpack Compose는 컴포지션(Composition) 트리를 따라 데이터를 암묵적으로 전달하는 메커니즘으로 CompositionLocal을 제공합니다. CompositionLocal을 사용하면 모든 컴포저블 함수의 매개변수로 데이터를 일일이 전달하지 않아도 하위 컴포저블에서 해당 데이터를 읽을 수 있습니다. CompositionLocal을 생성하는 팩토리 함수에는 compositionLocalOfstaticCompositionLocalOf 두 가지가 있으며, 제공된 값이 변경될 때 리컴포지션(Recomposition)에 미치는 영향이 서로 다릅니다. 이 차이는 성능에 직접적인 영향을 주기 때문에, 두 가지 방식의 동작 원리를 정확히 이해하는 것이 중요합니다.

이번 면접 질문을 통하여 아래 내용들을 학습하실 수 있습니다.

  • CompositionLocal의 목적과 컴포지션 트리를 통해 데이터를 전달하는 방식을 설명할 수 있습니다.
  • compositionLocalOf가 읽기 지점을 추적하여 타겟 리컴포지션을 트리거하는 과정을 이해할 수 있습니다.
  • staticCompositionLocalOf가 리컴포지션 추적을 완전히 생략하는 이유를 파악할 수 있습니다.
  • 값이 컴포지션 도중 변경되는지 여부에 따라 어떤 변형을 선택해야 하는지 판단할 수 있습니다.
  • 각 변형에서 제공된 값이 변경될 때 리컴포지션이 어떻게 동작하는지 예측할 수 있습니다.

CompositionLocal의 동작 원리

CompositionLocal은 기본값을 보유하고 있으며, 트리의 어느 지점에서든 CompositionLocalProvider를 통해 값을 오버라이드할 수 있습니다. Provider 하위에 있는 모든 컴포저블은 current 프로퍼티를 통해 현재 값을 읽게 됩니다. 이 방식을 활용하면 모든 중간 컴포저블에 값을 명시적으로 전달할 필요가 없어지므로, 이른바 "프로퍼티 드릴링(prop drilling)" 문제를 자연스럽게 해결할 수 있습니다.

CompositionLocal은 제공된 하위 트리(subtree) 범위로 한정됩니다. 루트에서 Provider를 설정하면 전체 트리에 영향을 미치고, 특정 화면 내부에 Provider를 중첩하면 해당 화면과 자식 컴포저블에만 영향을 미칩니다. 동일한 CompositionLocal에 대해 서로 다른 수준에 여러 Provider가 존재할 수 있으며, 이 경우 가장 가까운 상위 Provider가 우선적으로 적용됩니다. 면접에서 이 스코프 개념을 명확히 설명하실 수 있다면, CompositionLocal에 대한 깊은 이해를 보여주실 수 있을 것입니다.

두 팩토리 함수의 차이는 제공된 값이 변경될 때의 동작에 있습니다.

compositionLocalOf: 리컴포지션 인식 방식

compositionLocalOfcurrent 값을 읽는 컴포저블을 추적합니다. 제공된 값이 변경되면, 실제로 해당 값을 읽은 컴포저블만 리컴포지션됩니다. 따라서 컴포지션의 생명주기 동안 값이 변경될 것으로 예상되는 경우에 적합합니다. 테마 모드, 사용자 설정, 로컬라이제이션 데이터 등이 대표적인 사용 사례입니다.

val LocalThemeMode = compositionLocalOf { ThemeMode.Light }

@Composable
fun ThemeWrapper(
    themeMode: ThemeMode,
    content: @Composable () -> Unit
) {
    CompositionLocalProvider(
        LocalThemeMode provides themeMode
    ) {
        content()
    }
}

위의 코드에서 themeMode가 변경되면, LocalThemeMode.current를 읽는 모든 컴포저블이 새로운 값을 반영하기 위해 리컴포지션됩니다. 반면, 해당 값을 읽지 않는 컴포저블은 영향을 받지 않습니다. 이것이 바로 "타겟 리컴포지션(targeted recomposition)"의 핵심 원리입니다.

이 면접 질문은 구독자 전용입니다

Dove Letter를 구독하시면 안드로이드, 코틀린 개발 관련 독점 면접 질문의 전체 내용을 볼 수 있습니다.

구독하기