navigation 관련해서 코드를 분석하던 중, 공통 객체를 이용할 수 있도록 하는 로직이 있어 기록하게 되었다.
CompositionLocal
composable 사이에 특정 데이터나 객체를 전역 state처럼 두고 사용할 수 있는 방법이 있는데, 바로 "CompositionLocal"을 이용한 방법이다.
CompositionLocal은 compose에서 계층적으로 데이터를 전달하는 방법을 의미한다.
이 객체를 설정하면 하위 composable들은 자유롭게 이 객체의 정보에 접근할 수 있다.
navController를 예시로 들어, 아래와 같은 코드가 있다고 하자.
val navController = rememberNavController()
CompositionLocalProvider(navController.localNavController){
...
}
navController를 rememberNavController()를 통해 생성하고, 기억하였다.
그리고 이 객체를 하위 컴포넌트들이 공통으로 사용할 수 있도록 등록하고자 한다.
따라서 CompositionLocal로 등록하려고 하는데, 이 과정에 CompositionLocalProvider()가 사용된다.
CompositionLocalProvider
CompositionLocalProvider는 CompositionLocal 객체를 설정하고 하위 composable들에 값을 제공할 수 있도록 한다.
즉, 어떤 값이 하위 컴포저블에서 사용될지를 결정한다.
이때, CompositionLocal 객체로 navController.localNavController를 설정하였다.
localNavController는 navController를 CompositionLocal로 등록하는 역할이다.
그럼 하위 composable에서 navController에 접근하려면 어떻게 할까?
"CompositionLocal.current"를 통해 navController에 접근할 수 있다.
예를 들자면, 아래처럼 사용할 수 있는 것이다.
@Composable
fun SomeScreen() {
val navController = LocalNavController.current // CompositionLocal에서 navController 가져옴
Button(onClick = { navController.navigate("nextScreen") }) {
Text("Go to Next Screen")
}
}
"LocalNavController.current"를 통해 접근한다.
아래처럼 맨 위에서 사용했던 코드 안에서도 같은 방식으로 사용할 수 있다.
val navController = rememberNavController()
CompositionLocalProvider(navController.localNavController){
val controller = LocalNavController.current
...
}
compositionLocalOf와 provides
** 여기서 챗지피티도, 실제 내가 보고 있는 코드에서도 그렇고, LocalNavController를 CompositionLocal로 사용하길래 찾아본 결과
LocalNavController는 원래 존재하는 것이 아니라,
다음과 같이 compositionLocalOf를 사용해 직접 정의해 둬야 한다.
val LocalNavController = compositionLocalOf<NavController> {
error("NavController is not provided. Make sure to wrap your composable in CompositionLocalProvider.")
}
그리고 navigation을 설정할 때, 다음과 같은 설정이 필요하다
CompositionLocalProvider(LocalNavController provides navController)
여기서 provides는 CompositionLocalProvider와 함께 사용되어 CompositionLocal에 값을 제공할 때 쓰인다.
즉, CompositionLocal에 값을 연결하는 역할을 하며, 왼쪽에는 CompositionLocal을, 오른쪽에는 전달할 값을 쓴다.
'CS > Android' 카테고리의 다른 글
Coroutine (2) (0) | 2024.12.24 |
---|---|
Coroutine (1) (0) | 2024.12.17 |
Navigation (0) | 2024.12.16 |
Composable & Preview (0) | 2024.12.13 |
Ktlint vs Detekt vs Android Lint (1) | 2024.12.13 |