컴포지션은 Compose가 컴포저블을 실행할 때 빌드한 UI에 관한 설명이다. Compose 앱은 구성 가능한 함수를 호출하여 데이터를 UI로 변환한다. 상태가 변경되면 Compose는 영향을 받는 구성 가능한 함수를 새 상태로 다시 실행한다. 그러면 리컴포지션이라는 업데이트된 UI가 만들어진다. Compose는 자동으로 리컴포지션을 예약한다.
Compose는 초기 컴포지션 시 처음으로 컴포저블을 실행할 때 컴포지션에서 UI를 기술하기 위해 호출하는 컴포저블을 추적한다. 리컴포지션은 Compose가 데이터 변경사항에 따라 변경될 수 있는 컴포저블을 다시 실행한 다음 변경사항을 반영하도록 컴포지션을 업데이트하는 것이다.
컴포지션은 초기 컴포지션을 통해서만 생성되고 리컴포지션을 통해서만 업데이트될 수 있다. 컴포지션을 수정하는 유일한 방법은 리컴포지션을 통하는 것이다. 이렇게 하려면 Compose가 추적할 상태를 알아야 한다. 그래야 Compose가 업데이트를 받을 때 리컴포지션을 예약할 수 있다. 여기서는 추적할 상태가 amountInput 변수이므로 값이 변경될 때마다 Compose는 리컴포지션을 예약한다.
Compose는 선언적이므로 Compose를 업데이트하는 유일한 방법은 새 인수로 동일한 컴포저블을 호출하는 것이다. 이 인수로 UI상태를 표현하게 되는데 상태가 바뀔 때마다 재구성이 실행된다. 재구성할 때마다 함수 내의 로컬 변수들이 새로 생성되고 이는 UI의 불필요한 재성성과 성능 저하로 이어질 수 있다. 이를 방지하고 상태를 기억하여 UI의 효율성을 향상시키기 위해 'remember' 함수가 사용된다.
remember는 객체를 컴포지션에 저장하고, remember를 호출한 컴포저블이 컴포지션에서 삭제되면 그 객체를 잊는다.
mutableStateOf는 관찰 가능한 MutableState를 생성하는데, 이는 런타임 시 Compose에 통합되는 관찰 가능한 유형이다.
interface MutableState<T> : State<T> {
override var value: T
}
value가 변경되면 value를 읽는 구성 가능한 함수의 리컴포지션이 예약된다.
val mutableState = remember { mutableStateOf(default) }
var value by remember { mutableStateOf(default) }
val (value, setValue) = remember { mutableStateOf(default) }
위와 같은 방법으로 컴포저블에서 객체를 선언할 수 있다.
'remember' 함수를 사용하면 'mutableStateOf'로 생성된 상태를 Compose가 기억하게 된다.
그렇게 함으로써, UI가 재생성되어도 상태를 유지할 수 있다.
따라서, 화면이 리로드되거나 구성 변경 등이 발생하더라도 remember를 사용한 상태는 이전 상태를 유지하게 된다.
이렇게 함으로써 불필요한 UI의 재생성이 방지되고 성능이 향상되며, 사용자에게 더 부드러운 사용 경험을 제공할 수 있다.