Jetpack Compose Tutorial - Compose essentials

2 Thinking in Compose

Compose에서 UI는 object가 아닌 함수다. 따라서 UI를 참고(reference) 하거나 mutate 할 수 없다. 대신에 UI는 state나 전달하는 argument에 의해 변경된다.

What our UI should look like by providing the necessary states where our UI functions, but we’re not telling compose how it should render that state.

사용자가 UI와 interact를 하면, UI는 click과 같은 event를 emit한다. Event handler는 emit된 event를 보고 UI state가 변경되어야 하는지 판단한다. state가 변경되면, 그 state와 관련된 function과 UI element는 re-execute 된다.

state가 변경되었을 때 UI를 다시 그리는 작업을 recomposition이라고 한다.

3 Composable functions

compose function을 composable이라고 부른다.

composable은 immutable하다.

composable은 property나 global variable을 modify 하지 않음으로써 side effect가 없어야 한다.

recomposition은 다음과 같은 상황에 발생한다.

  1. composable에 새로운 parameter가 입력되었을 때
  2. internal state of composable이 변경되었을 때

MutableState : wrapping 된 값이 변경되면 recomposition이 schedule 된다.

화면 회전시에도 값이 유지되도록 하기 위해 remeberSaveable를 사용한다.

Composable function의 실행 순서는 코드가 적힌 순서와 무관하다. 앞에 있는 코드가 꼭 먼저 실행되는 것은 아니다.

Composable functions can run in parallel

side-effect는 꼭 함수 밖과 상호작용하는 것만 있는 것은 아니다. 아래의 items 변수를 만드는 것도 side-effect를 만든다.

@Composable
fun ListWithBug(myList: List<String>) {
    var items = 0
    Row(horizontalArrangement = Arrangement.SpaceBetween) {
        Column {
            for (item in myList) {
                Text("Item: $item")
                items++ // Side-effect
            }
        }
        Text("Count: $items")
    }
}

// No Side-effect
@Composable
fun ListWithBug(myList: List<String>) {
    Row(horizontalArrangement = Arrangement.SpaceBetween) {
        Column {
            for (item in myList) {
                Text("Item: $item")
            }
        }
        Text("Count: ${myList.size}")
    }
}

Recomposition은 가능한한 많은 것은 skip 한다. update 해야만 하는 최소한의 UI만 다시 실행한다.