TIL은 가벼운 개념정리 목적으로 작성되어 있습니다.
Jetpack Compose는 선언적 UI 프레임워크로, UI를 상태 기반으로 구성합니다. 즉, 화면에 표시되는 내용은 상태(state)에 따라 달라지며, 상태가 변경되면 UI가 자동으로 다시 그려집니다.
이 글에서는 Compose에서 상태를 어떻게 관리하는지, 그리고 이를 위해 제공되는 핵심 도구들에 대해 자세히 살펴보겠습니다.
Compose에서는 UI를 어떻게 그릴지 선언적으로 기술합니다. 예를 들어,
1
2
3
4
@Composable
fun Greeting(name: String) {
Text(text = "Hello, $name!")
}
여기서 name이라는 상태에 따라 화면에 표시되는 텍스트가 달라집니다. 상태가 변하면, Compose는 recomposition(재구성) 과정을 통해 변경된 상태를 반영하여 UI를 업데이트합니다.
Compose에서는 주로 remember, rememberSaveable, mutableStateOf를 활용해 상태를 관리합니다. 각 도구의 역할과 사용법을 살펴보겠습니다.
remember는 Composable 함수 내에서 한 번 생성된 값을 recomposition 동안 유지하도록 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
@Composable
fun RememberExample() {
// 최초 컴포지션 시 mutableStateOf 객체가 생성되고, 이후 재사용됨
var count by remember { mutableStateOf(0) }
Column {
Text(text = "Count: $count")
Button(onClick = { count++ }) {
Text("Increase")
}
}
}
여기서 remember에 의해 mutableStateOf(0)는 컴포저블의 메모리에 저장되고, recomposition 시 재생성되지 않습니다.
rememberSaveable은 remember와 기본 원리는 같지만, 추가적으로 구성 변경(예: 화면 회전) 시에도 상태를 저장하고 복원할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
@Composable
fun RememberSaveableExample() {
// 구성 변경 시에도 count 값이 유지됨
var count by rememberSaveable { mutableStateOf(0) }
Column {
Text(text = "Count: $count")
Button(onClick = { count++ }) {
Text("Increase")
}
}
}
이 코드는 기기 회전 등 구성 변경 상황에서도 사용자의 상태를 그대로 유지합니다.
mutableStateOf는 Compose에서 상태를 저장하고, 상태가 변경되면 이를 감지해 관련 UI를 자동으로 업데이트하도록 만드는 핵심 도구입니다.
getValue와 setValue를 구현하여, delegated property 방식(by)을 지원합니다.
1
2
3
4
5
6
7
8
9
10
11
@Composable
fun MutableStateExample() {
var name by mutableStateOf("Compose")
Column {
Text(text = "Hello, $name!")
Button(onClick = { name = "Jetpack Compose" }) {
Text("Change Name")
}
}
}
버튼을 클릭하면 name이 업데이트되고, 이로 인해 해당 컴포저블 함수가 재실행되어 UI가 최신 상태로 다시 그려집니다.
Compose의 상태 관리 시스템은 내부 Snapshot 시스템과 밀접하게 연동되어 있습니다.
mutableStateOf의 setValue가 호출되어 내부 값이 변경됩니다.이 메커니즘 덕분에, 상태 변경이 있을 때마다 직접 UI 업데이트를 신경 쓸 필요 없이 자동으로 최신 상태가 반영됩니다.
Kotlin의 delegated property를 활용하면 상태 관리 코드가 더욱 간결해집니다.
예를 들어, 위의 코드는 다음과 같이 작성할 수 있습니다:
일반 형태:
1
2
val countState = remember { mutableStateOf(0) }
// 접근 시: countState.value
Delegated Property 사용:
1
2
var count by remember { mutableStateOf(0) }
// 접근 시: count 직접 사용
Kotlin 컴파일러는 내부적으로 getValue와 setValue를 호출하여 countState.value에 접근하는 코드를 자동으로 생성해줍니다.
이렇게 하면 코드가 깔끔해지고, 상태를 다루는 로직이 간단해집니다.
Jetpack Compose에서 상태 관리는 선언적 UI를 구현하는 데 매우 중요한 역할을 합니다.
Compose의 이러한 상태 관리 메커니즘 덕분에 개발자는 UI와 상태 간의 동기화를 명시적으로 신경 쓸 필요 없이, 상태가 변경될 때마다 최신 UI를 쉽게 구현할 수 있습니다.