Compose 이해하기(2)

햄햄·2022년 5월 28일
0

Compose

목록 보기
2/7
post-thumbnail

Compose를 프로그래밍 할 때 알아야 할 사항

composable 함수는 순서와 관계없이 실행할 수 있음

composable 함수에 다른 composable 함수 호출이 포함되어 있다면 그 함수는 순서와 관계없이 실행될 수 있습니다. Compose에는 일부 UI요소가 다른 UI요소보다 우선순위가 높다는 것을 인지하고 그 요소를 먼저 그리는 옵션이 있습니다.

@Composable
fun ButtonRow() {
    MyFancyNavigation {
        StartScreen()
        MiddleScreen()
        EndScreen()
    }
}

StartScreen, MiddleScreenEndScreen 호출은 순서와 관계없이 발생할 수 있습니다. 각각의 함수는 독립적이어야 합니다.

composable 함수는 동시에 실행할 수 있음

Compose는 composable 함수를 동시에 실행하여 recomposition을 최적화할 수 있습니다. 최적화는 composable 함수가 백그라운드 스레드 풀 내에서 실행될 수 있음을 의미합니다. composable 함수가 ViewModel의 함수를 호출한다면, Compose는 동시에 여러 스레드에서 이 함수를 호출할 수 있습니다.
애플리케이션이 올바르게 작동하려면 모든 composable 함수에 side-effect가 없어야 합니다.

@Composable
@Deprecated("Example with bug")
fun ListWithBug(myList: List<String>) {
    var items = 0

    Row(horizontalArrangement = Arrangement.SpaceBetween) {
        Column {
            for (item in myList) {
                Text("Item: $item")
                items++ // Avoid! Side-effect of the column recomposing.
            }
        }
        Text("Count: $items")
    }
}

예를 들어, 위 코드의 items는 모든 recomposition을 통해 수정되기에 UI에 잘못된 값이 표시될 수 있습니다.

recomposition은 가능한 많이 건너뜀

UI의 일부가 업데이트 되어야 할 경우 Compose는 업데이트해야 하는 부분만 재구성합니다.

/**
 * Display a list of names the user can click with a header
 */
@Composable
fun NamePicker(
    header: String,
    names: List<String>,
    onNameClicked: (String) -> Unit
) {
    Column {
        // [header]가 변경될 때 recompose 될 것 입니다. 그러나 [name]이 변경될 때는 recompose되지 않습니다. 
        Text(header, style = MaterialTheme.typography.h5)
        Divider()

        // LazyColumn is the Compose version of a RecyclerView.
        // The lambda passed to items() is similar to a RecyclerView.ViewHolder.
        LazyColumn {
            items(names) { name ->
            	// item의 [name]이 업데이트되면 recompose됩니다. [header]가 변경될 때는 recompose되지 않습니다. 
                NamePickerItem(name, onNameClicked)
            }
        }
    }
}

/**
 * Display a single name the user can click.
 */
@Composable
private fun NamePickerItem(name: String, onClicked: (String) -> Unit) {
    Text(name, Modifier.clickable(onClick = { onClicked(name) }))
}

recomposition은 낙관적임

Compose가 composable의 매개변수가 변경되었을 수 있다고 생각할 때마다 recomposition이 시작됩니다. recomposition은 낙관적입니다. 즉, Compose는 매개변수가 다시 변경되기 전에 recomposition을 완료할 것으로 예상합니다. recomposition이 완료되기 전에 매개변수가 변경되면 Compose는 recomposition을 취소하고 새 매개변수를 사용하여 recomposition을 다시 시작할 수 있습니다.
recomposition이 취소되도 side-effect는 적용되므로 일관되지 않은 앱 상태가 발생할 수 있기에 모든 composable 함수가 멱등원(어떤 과정을 반복 수행 하여도 항상 동일한 결과)이고, side-effect가 없는지를 확인해야합니다.

composable 함수는 매우 자주 실행될 수 있음

composable 함수에서 비용이 많이 드는 작업을 실행하면 UI 버벅거림이 발생할 수 있습니다.

0개의 댓글