Compose 기초 - Compose 이해, Recomposition

Compose 이해 (원문)

💡개념이 헷갈리거나 제가 잘 모르거나 많은 사람들이 잘 모를 것 같은 것 위주로 정리

선언형 프로그래밍 패러다임이란?

findViewById(R.id.text).setText(aText)와 같은 명령형 코드의 단점은?

aText가 여러 View에서 사용된다고 가정했을 때 aText의 값이 바뀌면 모든 View를 수동조작해야 한다. View 하나라도 빠뜨리기 쉽다.

반면에 선언형 코드는 View가 데이터의 변화를 구독하도록 만들어서 UI 갱신을 자동화 한다.

선언형 프로그래밍 기법은 처음부터 화면 전체를 생성한 뒤에 필요한 변경사항만 자동 적용하는 방식으로 동작한다.

선언형 패러다임, 좀 더 자세히

simple

Compose의 선언형 접근방식에서는 Composable(@Composable 함수)들의 트리인 Composition을 빌드함으로써 UI를 초기화한다.

Composable은 setter 또는 getter 함수를 노출하지 않는다.

따라서 사실상 Composable은 객체로 노출되지 않으며 수동조작 할 수 없다.

dataflow

화면의 전체 데이터가 최상위 Composable의 매개변수로 전달되고, 이 데이터의 일부가 다시 하위 Composable로 전달된다.

eventflow

onClick과 같은 사용자 이벤트는 하위 Composable에서 상위 Composable로 전달된다. 상위에서 데이터가 변경되면 다시 계층구조 아래로 전달된다.

동적 컨텐츠로 구현 가능

@Composable 함수는 Kotlin으로 작성되기 때문에 if, for 문법을 사용하여 조건에 따라 UI를 빌드할 수 있다.

@Composable
fun Greeting(flag: Boolean) {
    if (flag) {
        Text("Hello")
    }
}

Recomposition이란?

  1. @Composable 함수의 매개변수 또는 로컬변수가 변한다.
  2. 이 변수를 사용하는 하위의 @Composable 함수가 재호출된다.
  3. 그리고 대응되는 UI가 갱신된다.

이 프로세스를 Recomposition(재구성)이라고 한다.

@Composable 
fun Greeting(name: String) {
    // name이 변하면 name을 사용하는 Text()가 재호출된다.
    Text("Hello $name")
}

Recomposition에 대해 알아둘 점

입력의 변화가 없는 @Composable 함수는 Recomposition에서 제외될 수 있다. (=Smart Recomposition) recomposition

또 애니메이션 렌더링 중의 모든 프레임에서 @Composable 함수가 빈번히 호출될 수 있다.

@Composable 함수는 빈번히 호출될 수 있기 때문에 함수 안에서 비용이 많이 드는 작업을 피해야 한다. 꼭 필요하다면 백그라운드 코루틴을 통해 작업을 실행한다.

@Composable 함수는 순서와 관계없이 호출될 수 있다.

@Composable 함수는 동시에 호출될 수 있다.

Recomposition은 낙관적이며 취소될 수 있다.

이런 이유들로 인해 @Composable 함수에서 사이드이펙트를 발생시키면 사이드이펙트의 결과를 사용자가 예측하기 어렵다.

*사이드이펙트 예시 : 전역변수, SharedPreference 등의 값을 변경하는 행위, 한 번만 실행해야 하는 작업