본문 바로가기
2학년 2학기/모바일 소프트웨어 - 안드로이드 스튜디오

State hoisting이 뭐지?

by kkkkk1023 2024. 11. 20.

우선, state에 대해서 알아보자.

 

State

: UI의 현재 상태를 나타내는 데이터이다. 예를 들어, 화면에 표시되는 숫자 값이 있다면 그 숫자가 State이고, 버튼 클릭에 따라 값이 변경되면 State의 값이 업데이트되어 UI도 변경된 것이다. 

 


State 선언

var count by remember { mutableStateOf(0) }

 

state는 위의 형태와 같이 선언이 되는데 mutableStateOf는 state의 값이 변경될 때, 관련 UI가 다시 렌더링되도록 만드는 함수이다. 

또한 ,remember는 UI가 렌더링 되더라도 state의 값이 변경되지 않고 유지되도록 만드는 것이다. 

 

 

 

 

 

 


Stateful과 Stateless

 

Stateful: 상태가 스스로 관리하는 방식이다. 쉽게 말해서 Composable 내부에서 State를 정의하고, 그 상태를 업데이트하거나 사용하는 로직을 포함한다. 

// Stateful 예시

@Composable
fun StatefulCounter() {
    var count by remember { mutableStateOf(0) }
    
    Button(onClick = { count++ }) {
        Text("Count: $count")
    }
}

 

 

 

 

Stateless: 상태를 관리하지 않고, 상태를 외부에서 전달 받아 사용하는 방식이다. State를 부모가 관리하며, Composable은 단순히 UI를 그리는 역할만 한다. 이렇게 하면 재사용성과 테스트 가능성이 높아진다는 장점이 있다. 

 

// Stateless 예시

@Composable
fun StatelessCounter(count: Int, onIncrement: () -> Unit) {
    Button(onClick = onIncrement) {
        Text("Count: $count")
    }
}

 


 

State Hoisting

: State Hoisting이란, Stateless하게 state를 관리하는 방식이다.

 

쉽게 말해서 Stateful은 Composable에서 상태를 스스로 관리하기 때문에 해당 Composable을 다른 기능을 하게 만들기 어려워진다, 하지만 Stateless하면 상태를 부모(즉, 호출하는 곳)Composable에서 관리하기 때문에 UI Composable을 재상요하고 테스트하기 쉬워진다. 

 

부모 Composable

@Composable
fun CounterHost() {
    var count by remember { mutableStateOf(0) }  // 부모에서 상태 관리

    StatelessCounter(
        count = count,               // 상태를 자식으로 전달
        onIncrement = { count++ }    // 상태 변경 로직 전달 - 콜백 함수
    )
}

 

 

자식 Composable

@Composable
fun StatelessCounter(count: Int, onIncrement: () -> Unit) {
    Button(onClick = onIncrement) {  // 상태 변경 요청을 부모로 전달
        Text("Count: $count")        // 전달받은 상태를 UI에 표시
    }
}

 

onIncrement는 콜백 함수이기 때문에 버튼이 클릭되어 onIncrement가 실행되면 부모 Composable에 상태 변경을 요청하게되고, UI도 재렌더링된다. 

 

 

이런식으로 자식 Composable은 UI만 관리하고 상태는 부모 Composable에서 관리하는 것을 State Hoisting이라고 한다.