CS/Android

공통 객체 이용하기 - CompositionLocal

졔졔311 2024. 12. 17. 09:08
728x90
반응형

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을, 오른쪽에는 전달할 값을 쓴다.

728x90
반응형

'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