본문 바로가기

안드로이드/Compose State

[안드로이드 Jetpack Compose] remember와 MutableState의 3가지 사용 방법


안녕하세요. 이번 포스팅에서는 안드로이드 Jetpack Compose에서 상태 변수를 관리하기 위해서 필수적으로 사용하는 remember와 MutableState에 대해서 설명하고, MutableState의 3가지 사용방법을 코드 예제와 함께 살펴보겠습니다.

상태값 변경에 따른 업데이트 루프
상태값 변경에 따른 업데이트 루프

1. MutableState와 Remember 개념

안드로이드 Jetpack Compose에서 UI 로직을 처리할 때는 주로 mutableStateOf와 remember를 사용합니다. 여기서 compose가 생소하신 분들은 remember의 역할에 대해 모를 수 있습니다.

Compose UI는 선언형 UI 패러다임을 따르는 방식으로써 상태가 변할 때마다 렌더링을 다시 합니다. 이렇게 다시 렌더링이 되는 현상을 Compose에서는 리컴포지션이라고 부릅니다. 리컴포지션이 발생하면 컴포넌트 안에 선언한 변수도 다시 초기화가 진행되는데, 최초에만 초기화를 진행하고 이전 상태값을 기억하기 위해서는 remember를 사용해야 합니다.

아래 코드에서 remember를 사용하지 않았다면 사용자가 TextField의 값을 바꿨을 때, 다시 "initial name"으로 초기화돼서 값이 변경되지 않는 현상이 발생합니다. 그래서 mutableStateOf와 함께 remember를 사용하게 됩니다.

@Composable
fun Memo() {
    val memo = remember { mutableStateOf("initial name") }
    TextField(
        value = memo.value,
        onValueChange = { memo.value = it }
    )
}

2. MutableState의 사용방법 3가지

위에서 선언한 mutableStateOf는 3가지 방법으로 사용할 수 있습니다. 어떤 방법으로 사용해도 상관은 없지만, 다른 사람이 작업한 내용을 확인할 때 모든 사용방법을 알고 있어야 코드를 쉽게 파악할 수 있으므로 모두 알아두는 것이 좋습니다.

2-1. mutableStateOf 방법

위의 예제에서 사용했던 방법입니다. 개인적으로는 해당 방법이 가장 기본적인 사용방법이라고 생각합니다. 그러나 value 프로퍼티에 값이 저장돼 있으므로 memo.value와 같이 코드가 좀 더 길어지는 단점이 있습니다. 그래서 저는 by 키워드를 선호하는 편입니다.

2-2. by mutableStateOf 방법 (Delegation)

by 키워드를 사용하면 getter와 setter를 해당 상태값에 위임하게 됩니다. 아까는 value 프로퍼티에 접근을 해서 값을 가져오거나 수정해 주었지만 by 키워드를 사용하면 상태값에 직접 접근할 수 있습니다. 즉, 위의 예제는 아래의 코드처럼 수정할 수 있습니다. 여기서 setter도 위임받았으므로 가변 변수인 var로 변경해야 합니다.

@Composable
fun Memo() {
    var memo by remember { mutableStateOf("initial name") }
    TextField(
        value = memo,
        onValueChange = { memo = it }
    )
}

2-3. 코틀린 구조분해할당 방법 (Destructuring)

구조분해란 객체가 관리하는 값을 한 번에 받을 수 있는 기능입니다. 타입스크립트로 웹 개발을 해본 분들이라면 구조분해할당 방법에 친숙하실 수 있습니다. 코틀린도 이러한 구조분해할당 문법을 지원하고 있으며, MutableState에 해당 기능을 포함합니다. 아래는 구조분해할당 방법을 제공하기 위한 MutableState의 내부 코드입니다.

@Stable
interface MutableState<T> : State<T> {
    override var value: T
    operator fun component1(): T
    operator fun component2(): (T) -> Unit
}


그래서 MutableState를 사용할 때, 아래처럼 구조분해할당 방법으로 사용할 수 있습니다. component1에 해당되는 상태값과 component2에 해당되는 상태값 저장 함수를 동시에 할당받아서 사용한 있는 모습입니다.

@Composable
fun Memo() {
    val (memo, setMemo) = remember { mutableStateOf("initial name") }
    TextField(
        value = memo,
        onValueChange = { setMemo(it) }
    )
}

3. MutableState, Remember 사용방법 정리

이번 시간에는 안드로이드 Jetpack Compose에서 MutableState와 Remember의 역할과 사용방법에 대해 알아보았습니다. MutableState를 사용할 때는 3가지 방법이 제공되고 있으며, 각 방법 모두 동일한 기능을 수행합니다. 다만, getter와 setter를 위임하는 by 키워드 방법과 구조분해할당 방법을 적절하게 사용하면 중복 코드를 많이 줄일 수 있습니다.

개인적으로는 by 키워드 방법을 많이 사용합니다. 변수 하나로 간단하게 getter와 setter 기능을 모두 수행하는 양방향 바인딩 스타일의 코딩 방식을 선호하기 때문입니다.

하지만, 어떤 방법을 사용해도 문제는 없으며 여러분의 코딩 스타일이나 회사의 코딩 컨벤션에 알맞게 사용하면 좋을 것 같습니다.

반응형