Compose의 상태 (2)

k_hyun·2023년 6월 19일
0

상태 호이스팅

내부 상태를 갖는 컴포저블은 재사용 가능성이 적고 테스트하기가 더 어려운 경향이 있다.

상태 호이스팅은 컴포저블을 스테이트리스(Stateless)로 만들기 위해 상태를 컴포저블의 호출자로 옮기는 패턴

컴포저블이 가능한 한 적게 상태를 소유하고 적절한 경우 컴포저블의 API에 상태를 노출하여 상태를 끌어올릴 수 있도록 컴포저블을 디자인해야 한다.

Counter 분리

@Composable
fun StatefulCounter(modifier: Modifier) {
    var waterCount by remember { mutableStateOf(0) }

    var juiceCount by remember { mutableStateOf(0) }

    StatelessCounter(waterCount, { waterCount++ })
    StatelessCounter(juiceCount, { juiceCount++ })
}

@Composable
fun StatelessCounter(count: Int, onIncrement: () -> Unit, modifier: Modifier = Modifier) {
   Column(modifier = modifier.padding(16.dp)) {
       if (count > 0) {
           Text("You've had $count glasses.")
       }
       Button(onClick = onIncrement, Modifier.padding(top = 8.dp), enabled = count < 10) {
           Text("Add one")
       }
   }
}

기존에 상태를 가진 Counter를 Stateful, Statelesss 컴포저블로 분리할 수 있다.


사용자가 juiceCount의 값을 변경하면 StatefulCounter가 리컴포즈 된다.

그리고 juiceCount를 읽는 StatelessCounter(juiceCount)만 리컴포즈 된다.
하지만 StatelessCounter(waterCount)는 리컴포즈 되지 않음

관찰 가능한 MutableList

목록에서 작업을 삭제하는 동작을 추가하려면 먼저 목록을 변경 가능한 목록으로 만들어야 한다.

이를 위해 변경 가능한 객체(예: ArrayList 또는 mutableListOf,)를 사용하면 작동하지 않음

주의 사항

  //경고: 대신 mutableStateListOf API를 사용하여 목록을 만들 수 있습니다.
  //그러나 이를 사용하는 방식으로 인해 예기치 않은 리컴포지션이 발생하고 UI 성능이 최적화되지 않을 수 있습니다.

//목록을 정의하고 작업을 다른 작업에 추가하면 모든 리컴포지션에 중복된 항목이 추가됩니다.

// Don't do this!

val list = remember { mutableStateListOf<WellnessTask>() }

list.addAll(getWellnessTasks())

대신 단일 작업으로 초깃값을 사용하여 목록을 만든 후 다음과 같이 remember 함수에 전달합니다.

// Do this instead. Don't need to copy

val list = remember {

mutableStateListOf<WellnessTask>().apply { addAll(getWellnessTasks()) }

}

작동 순서

0개의 댓글