[Android] 상태호이스팅 패턴

정상준·2023년 1월 16일
0
post-thumbnail

📝 상태호이스팅이란

선언형 UI인 Compose의 장점은 Stateless하기 때문이다. 하지만 Compose로 앱을 만들다 보면 어쩔 수 없이 Stateful할 때 있는데 이때 상태호이스팅 패턴으로 앱을 만들어 Composable 함수를 Stateless하게 만들어 주는 것이다.

호이스팅이 필요한 경우

  • 상태를 여러 Composable 함수와 공유하는 경우
  • 앱에서 재사용할 수 있는 스테이트리스(Stateless) 컴포저블을 만드는 경우

즉 상태 호이스팅이란 구성요소를 스테이트리스(Stateless)로 만들기 위해 상태를 다른 함수 위로 옮기는 패턴입니다.

이 패턴이 컴포저블에 적용되는 경우 컴포저블에 매개변수 2개가 추가될 때가 많습니다.

  • value: T 매개변수 - 표시할 현재 값
  • onValueChange: (T) -> Unit - 사용자가 텍스트 상자에 텍스트를 입력하는 경우 등 값이 변경될 때 상태가 업데이트될 수 있도록 트리거되는 콜백 람다입니다.

🖨 예시

@Composable
fun TipTimeScreen() {
   var amountInput by remember { mutableStateOf("") }

   val amount = amountInput.toDoubleOrNull() ?: 0.0
   val tip = calculateTip(amount)

   Column(
       modifier = Modifier.padding(32.dp),
       verticalArrangement = Arrangement.spacedBy(8.dp)
   ) {
       Text(
           text = stringResource(R.string.calculate_tip),
           fontSize = 24.sp,
           modifier = Modifier.align(Alignment.CenterHorizontally)
       )
       Spacer(Modifier.height(16.dp))
       EditNumberField(value = amountInput,
           onValueChange = { amountInput = it }
       )
       Spacer(Modifier.height(24.dp))
       Text(
           text = stringResource(R.string.tip_amount, tip),
           modifier = Modifier.align(Alignment.CenterHorizontally),
           fontSize = 20.sp,
           fontWeight = FontWeight.Bold
       )
   }

}

@Composable
fun EditNumberField(
       value: String,
       onValueChange: (String) -> Unit
   ) {
   TextField(
       value = value,
       onValueChange = onValueChange,
       label = { Text(stringResource(R.string.cost_of_service)) },
       modifier = Modifier.fillMaxWidth(),
       singleLine = true,
       keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
   )
}

📍 참고: 실제 앱에서는 컴포저블의 기능에 따라 컴포저블을 100% 스테이트리스(Stateless)로 하는 것은 어려울 수 있습니다. 컴포저블이 가능한 한 적게 상태를 소유하고 적절한 경우 컴포저블의 API에 상태를 노출하여 상태를 호이스팅할 수 있도록 컴포저블을 디자인해야 합니다.

profile
안드로이드개발자

0개의 댓글