CompositionLocal
암시적으로 Composition을 통해 데이터를 전달하는 도구
UI 트리의 특정 범위에서 암시적으로 데이터 전달 가능
Compose에서 일반적으로 매개변수로 데이터를 전달한다
하지만 색상이나 텍스트 스타일처럼 자주 사용되는 데이터일 경우, 모든 함수에 매개변수로 전달하는 것은 번거로울 수 있다
이런 경우 CompositionLocal을 사용하면 명시적으로 매개변수로 전달할 필요 없이 데이터를 사용할 수 있다
동작 방식
CompositionLocal 정의
compositionLocalOf나 staticCompositionLocalOf 사용
fun <T> compositionLocalOf(
policy: SnapshotMutationPolicy<T> =
structuralEqualityPolicy(),
defaultFactory: () -> T
): ProvidableCompositionLocal<T> = DynamicProvidableCompositionLocal(policy, defaultFactory)
fun <T> staticCompositionLocalOf(defaultFactory: () -> T): ProvidableCompositionLocal<T> =
StaticProvidableCompositionLocal(defaultFactory)
CompositionLocal
@Stable
sealed class CompositionLocal<T> constructor(defaultFactory: () -> T) {
internal val defaultValueHolder = LazyValueHolder(defaultFactory)
internal abstract fun updatedStateOf(value: T, previous: State<T>?): State<T>
// 가장 가까운 CompositionLocalProvider에서 제공된 값
@OptIn(InternalComposeApi::class)
inline val current: T
@ReadOnlyComposable
@Composable
get() = currentComposer.consume(this)
}
새로운 값을 제공하려면 provides 중위 함수를 사용한다
infix fun provides(value: T) = ProvidedValue(this, value, true)
provides 함수는 CompositionLocalProvider와 CompositionLocal 키를 value에 연결
CompositionLocalProvider
CompositionLocal의 값을 변경할 범위 지정 (content 람다)
@Composable
@OptIn(InternalComposeApi::class)
fun CompositionLocalProvider(value: ProvidedValue<*>, content: @Composable () -> Unit) {
currentComposer.startProvider(value)
content()
currentComposer.endProvider()
}
compositionLocal을 사용하는 예시
// CompositionLocal 정의
val LocalContentColor = compositionLocalOf { Color.Gray }
// content 람다 내에서 current를 사용하면 해당 CompositionLocal의 변경된 값을 가져올 수 있다
@Composable
fun ContentWithLocalColor() {
val contentColor = LocalContentColor.current // 현재 CompositionLocal 값
Text("${contentColor.toString()}", color = contentColor)
}
@Composable
fun Main() {
// 기본값 표시
ContentWithLocalColor()
// CompositionLocalProvider를 사용하여 값 변경
CompositionLocalProvider(LocalContentColor provides Color.Blue) {
ContentWithLocalColor() // 파란색으로 표시
}
// 다른 값으로 변경
CompositionLocalProvider(LocalContentColor provides Color.Red) {
ContentWithLocalColor() // 빨간색으로 표시
}
}
'Compose' 카테고리의 다른 글
[ComposeInternals] Compose 컴파일러(1) - 어노테이션 (0) | 2025.03.03 |
---|---|
[ComposeInternals] Composable 함수들 (0) | 2025.03.03 |
[Compose] Compose 아키텍처 레이어링 (0) | 2025.02.23 |
[Compose] Compose 아키텍처 (0) | 2025.02.23 |
[Compose] UI 상태 저장 및 복원 (0) | 2025.02.22 |