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를 쉽게 구현할 수 있습니다.