[Compose] Jetpack Compose 상태 관리 기초

이번 글에서는 remember, rememberSaveable, State, MutableState, SnapshotStateList, 그리고 ViewModel에 대해 알아보겠습니다.

 

🌟 remember: 컴포저블 내에서 상태를 기억하기

remember는 컴포저블 함수가 재구성될 때 값을 기억하도록 돕는 유틸리티입니다.

이 함수를 사용하면 재구성(recomposition) 중에도 값이 초기화되지 않고 유지됩니다.

@Composable
fun MyComposable() {
    val count = remember { mutableStateOf(0) }

    Button(onClick = { count.value++ }) {
        Text("Count: ${count.value}")
    }
}

위 코드에서는 버튼 클릭 시 count가 증가하지만, 컴포저블이 재구성되어도 count는 초기화되지 않습니다.

 

💾 rememberSaveable: 상태를 저장하고 복원하기

remember와 유사하지만, rememberSaveable은 프로세스가 종료되거나 화면 회전 등으로 인해 UI가 재구성되더라도 상태를 유지합니다. 이는 번들에 저장 가능한 값(예: Parcelable, Serializable, 또는 Bundle)을 자동으로 저장합니다.

@Composable
fun MySaveableComposable() {
    val count = rememberSaveable { mutableStateOf(0) }

    Button(onClick = { count.value++ }) {
        Text("Count: ${count.value}")
    }
}

이제 화면 회전과 같은 상황에서도 count는 유지됩니다.

 

⚙️ State와 MutableState: 상태의 읽기와 쓰기

State와 MutableState는 Jetpack Compose에서 상태를 나타내는 기본적인 인터페이스입니다.

State는 읽기 전용 상태를 나타내며, MutableState는 상태를 변경할 수 있습니다.

@Composable
fun StateExample() {
    val text = remember { mutableStateOf("Hello, Compose!") }

    Column {
        Text(text.value)
        Button(onClick = { text.value = "Hello, Kotlin!" }) {
            Text("Change Text")
        }
    }
}

이 예제에서 text는 MutableState로 정의되었으며, 버튼 클릭 시 값을 변경할 수 있습니다.

 

📋 SnapshotStateList: 동적 리스트 관리

SnapshotStateList는 Compose에서 상태가 포함된 동적 리스트를 나타냅니다.

리스트의 내용이 변경될 때마다 컴포저블은 자동으로 재구성됩니다.

@Composable
fun ListExample() {
    val items = remember { mutableStateListOf("Item 1", "Item 2", "Item 3") }

    Column {
        items.forEach { item ->
            Text(item)
        }

        Button(onClick = { items.add("Item ${items.size + 1}") }) {
            Text("Add Item")
        }
    }
}

이 예제에서는 리스트에 아이템을 추가할 때마다 UI가 자동으로 업데이트됩니다.

 

🧠 ViewModel: Compose와 아키텍처 컴포넌트의 통합

ViewModel은 Compose에서 장기적으로 유지되어야 하는 상태를 관리하는 데 유용합니다.

이는 화면 회전과 같은 구성 변경에도 상태를 유지할 수 있도록 해줍니다.

ViewModel을 사용하여 Compose와 기존 Android 아키텍처 컴포넌트를 통합할 수 있습니다.

 

class MyViewModel : ViewModel() {
    var count by mutableStateOf(0)
        private set

    fun increment() {
        count++
    }
}

@Composable
fun ViewModelExample(viewModel: MyViewModel = viewModel()) {
    Column {
        Text("Count: ${viewModel.count}")
        Button(onClick = { viewModel.increment() }) {
            Text("Increment")
        }
    }
}

위 코드에서는 ViewModel을 사용해 상태를 관리하며, 이 상태는 구성 변경에도 유지됩니다.