[Android] State Hoisting

hy3.nji·2023년 7월 23일
0

Jetpack Compose 🎀

목록 보기
4/6

State Hoisting

: Yes
tag: Hoisting, State, stateful, stateless
날짜: 2023년 4월 8일

용어 정리


  1. State
    • a value holder
    • 시간이 지나 변화할 수 있는 모든
      • 로그인 창에서 ID를 입력하는 텍스트필드

      • 사용자가 입력을 할 때마다(자판 하나를 누를 때마다), 텍스트 필드 값이 변화함.

      • 이 때, 텍스트필드의 값을 State를 이용해서 정의할 수 있다.

        @Composable
        fun EditNumberField() {
        
            var amountInput by remember { mutableStateOf("")}
        
         //   var amountInput = mutableStateOf("0")
        
            TextField(
                value = amountInput,
                onValueChange = { amountInput = it }    
        		)
        
        }
    • Composable 함수가 실행될 때, State에서 값을 읽어 value에 할당한다.
    • observable
      • 계속 값의 변화를 확인한다. ⇒ 값이 변경되면 composable 함수를 재실행하여 UI에 값의 변화를 반영하기 위해서!
  2. State Hoisting
    • State hoisting in Compose is a pattern of moving state to a composable's caller to make a composable stateless.
    • state를 composable을 호출한 다른 composable으로 옮기는 패턴이다.
  3. Stateful Composable
    • State를 가진 Composable
  4. Stateless Composable
    • State를 가지지 않은 Coomposable

State Hoisting을 왜 쓸까?


  1. State Hoisting 예제 - (1)

    // 기존의 코드
    @Composable
    fun EditNumberField() {
        var amountInput by remember { mutableStateOf("")}
        
        TextField(
            value = amountInput,
            onValueChange = { amountInput = it },
            label = { Text(stringResource(R.string.cost_of_service)) },
            modifier = Modifier.fillMaxWidth(),
            singleLine = true,
            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
        )
    }
    // 바꾼 composable 코드
    @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)
        )
    }
    
    // EditNumberField를 호출할 때
    var amountInput by remember { mutableStateOf("")}
    
    EditNumberField(amountInput, {amountInput = it})
    

    ⇒ 변수를 사용하는 composable에서 변수를 정의하는 것이 아니라, composable을 호출하는 곳에서 변수를 정의함.

    ⇒ TextField는 value(UI에 표시하려고 하는 데이터 값)와 onValueChange(새로운 입력이 있을 때, value값을 변경하는 람다 함수)를 매개 변수로부터 할당.

  2. State Hoisting 예제 - (2)

    //State Hoisting 적용 예제 2
    @Composable
    fun HelloScreen() {
        var name by rememberSaveable { mutableStateOf("") }
    
        HelloContent(name = name, onNameChange = { name = it })
    }// UI를 호출하는 함수
    
    @OptIn(ExperimentalMaterial3Api::class)
    @Composable
    fun HelloContent(name: String, onNameChange: (String) -> Unit) {
        Column(modifier = Modifier.padding(16.dp)) {
            Text(
                text = "Hello, $name",
                modifier = Modifier.padding(bottom = 8.dp),
                style = MaterialTheme.typography.bodyMedium
            )
            OutlinedTextField(value = name, onValueChange = onNameChange, label = { Text("Name") })
        }
    }// UI를 기술하는 함수
  3. State Hoisting pattern

    • Unidirectional data flow
    • UI에서 State를 표시하는 ComposableState를 저장하고 변경하는 Composable분리할 수 있다.
    • HelloScreen으로부터 HelloContent로 State가 내려오고, HelloContent로부터 HelloScreen으로 event가 올라간다.
      • 사용자 입력인 event가 발생하면 HelloContent가 HelloScreen에게 전달
      • State가 변하면 HelloScreen이 HelloContent에 전달
  4. 이용

    • Share the state with multiple composable functions.
      • 동일한 변수를 다른 Composable 함수에 이용해야 하는 경우.
    • Create a stateless composable that can be reused in your app.
      • 동일한 Composable이 다른 변수를 반영해야 하는 경우.

        ⇒ 변수와 composable의 재사용성이 높아진다!

profile
Android Developer

1개의 댓글

comment-user-thumbnail
2023년 7월 23일

좋은 정보 얻어갑니다, 감사합니다.

답글 달기