JetPackCompose: Stateless Composable

timothy jeong·2022년 3월 27일
0

Android with Kotlin

목록 보기
68/69

Stateful vs Stateless

위의 TextFieldExample composable 은 내부적으로 state 를 가지고 있는데, stateful 한 함수이다. 내부적으로 state를 가지고 있을 경우 state 에 대한 별도의 처리가 필요하지 않기 때문에 composable caller 가 사용하기 편하기는 하지만,재사용성이 떨어지고 테스트하기 어려워진다.

이때 state hoisting 이라는 것을 이용하여 stateless 한 composable 을 구성할 수 있다.

hoisting 이란 함수안에 선언되는 변수들을 유효범위 최상단에 모아서 선언하는 것을 의미한다.

State hoisting

State hoisting 은 composable caller 에게 state 를 옮겨서, composable 을 stateless 하게 만드는 방법이다.

JetPack Compose 에서 보통 state를

  • value: T
  • onValueChange: (T) -> Unit

두 부분으로 나누는 패턴을 이용하여 State hoisting 을 구현한다. 이전 포스팅의 TextFieldExample 을 stateless 하게 만든다면 다음과 같이 만들 수 있다.

class StateActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            var name by remember { mutableStateOf("")}
            ComposeTestTheme {
                TextFieldExample(
                    state = name,
                    onValueChange = { name = it }
                )
            }
        }
    }
}

@Composable
fun TextFieldExample(state: String, onValueChange: (String)->Unit) {
    Column(modifier = Modifier.padding(16.dp)) {
        if (state.isNotEmpty()) {
            Text(
                text = "Hello, $state!",
                style = MaterialTheme.typography.h2
            )
        }
        OutlinedTextField(
            value = state,
            onValueChange = onValueChange,
            label = { Text("Name") },
            modifier = Modifier.padding(top = 8.dp),
        )
    }
}

이러한 hoisting의 결과 하나의 Composable 이 State 를 가지기 때문에 관리가 수월해진다. 하지만 하위 composable에 state 를 넘겨야하는 상태라면 함수 파라미터로 계속해서 동일한 State 를 넘겨줘야해서, 최상단의 composable 이 너무 많은 파라미터를 받게되는 현상이 나타날 수 있고, 이로 인해서 오히려 재사용성이 떨어지는 경우도 있을 수 있다. 이럴때는 ViewModel 에서 State 를 관리하도록 하면 해결될 것이다.

중요한 속성

이러한 hoist 를 한 state 는 몇가지 중요한 속성을 갖게된다.

  • Single source of truth : 단일 state 가 주입되기 때문에 state 관리가 수월하다.

  • Encapsulated : state 를 주입하는 stateful composable 에서만 조작이 가능하다.

  • Shareable : hoist 된 state 는 여러 composable 에서 사용할 수 있다.

  • Interceptable: state 에 변화가 있을때 stateful composable 는 이를 적용하지, 무시할지 결정할 수 있다.

  • Decoupled: 굳이 모든 state 가 composable 내에 위치할 필요가 없어진다.

profile
개발자

0개의 댓글