Android/Compose

[Compose] Compose에서의 상태

JunsuKim 2023. 4. 3.
728x90

단순히 행과 열, 버튼을 생성하는 것은 정적 레이아웃에 해당한다.

이제 사용자에 의해 변경사항이 있을 때마다 화면과의 상호작용을 하는 동적 레이아웃을 알아보자.

@Composable
fun Greeting(name: String) {
    var expanded = false

    Surface(
        modifier = Modifier.padding(24.dp)
    )
    {
        Row(
            modifier = Modifier
                .padding(24.dp)
                .border(1.dp, Color.Black)
        ) {
            Column(Modifier.padding(3.dp)) {
                Text(text = "Hello, ")
                Text(name)
            }
            ElevatedButton(onClick = {expanded = !expanded} ) {
                Text(if(expanded) "Show less" else "Show more")
            }
        }
    }
}

이러한 코드가 있을 때 에뮬레이터의 결과는 다음과 같다.

여기서 "Show more" 버튼을 클릭했을 때의 기댓값은 버튼의 text가 "Show less"로 바껴야 한다.

하지만 버튼을 눌렀을 때, 아무 변화가 없는 것을 확인할 수 있다.

expanded 변수에 다른 값을 설정하더라도 Compose 상에서 변경된 값을 감지하지 않기 때문이다.

 

Compose 앱은 Composable한 함수를 호출하여 데이터를 UI로 변환하는데, 데이터가 변경된다면 새 데이터로 함수를 다시 실행하여 업데이트된 UI를 만든다. 이를 리컴포지션이라고 한다.

 

Composable에 내부 상태를 추가하기 위해서는 mutableStateOf 함수를 사용하면 된다.

mutableStateOf 함수를 사용하면 Compose가 State를 읽는 함수를 재구성한다.

여기서 State, mutableStateOf는 어떤 값을 보유하고 있으며, 그 값이 변경될 때마다 UI 업데이트를 트리거하는 인터페이스이다.

 

그렇다면 Composable 안의 변수에 mutableSetOf을 할당하면 원하는 것처럼 작동이 될까?

아쉽게도 mutableSetOf을 할당하는 것만으로는 정상 작동이 될 수 없다.

false값을 가진 변경 가능한 새 상태를 재설정하여 Composable을 다시 호출할 때 언제든지 리컴포지션이 일어날 수 있기 때문이다.

 

여러 리컴포지션 간의 상태를 유지하기 위해서는 remember를 사용해 변경 가능한 상태를 기억해주어야 한다.

remember는 다음과 같이 사용된다.

@Composable
fun Greeting(name: String) {
    val expanded = remember { mutableStateOf(false) }

    Surface(
        modifier = Modifier.padding(24.dp)
    )
    {
        Row(
            modifier = Modifier
                .padding(24.dp)
                .border(1.dp, Color.Black)
        ) {
            Column(Modifier.padding(3.dp)) {
                Text(text = "Hello, ")
                Text(name)
            }
            ElevatedButton(
                onClick = { expanded.value = ! expanded.value }
            ) {
                Text(if(expanded.value) "Show less" else "Show more")
            }
        }
    }
}

버튼을 눌렀을 때 버튼의 텍스트가 "Show more"에서 "Show less"로 바뀌는 것을 확인할 수 있다.

 

remember는 리컴포지션을 방지하는데 사용되므로 상태가 재설정되지 않는다.

Composable 함수는 상태를 자동으로 "구독"하며, 상태가 변경되면 필드를 읽는 Composable이 재구성되어 업데이트를 표시한다.

728x90

'Android > Compose' 카테고리의 다른 글

[Compose] Compose의 Side-Effect(2)  (0) 2023.05.09
[Compose] Compose의 Side-Effect(1)  (0) 2023.04.25
[Compose] Composable 재사용  (0) 2023.03.27
[Compose] Surface, Modifier, Row, Column, 버튼 생성  (0) 2023.03.27
[Compose] Compose란?  (0) 2023.03.19

댓글