-
Notifications
You must be signed in to change notification settings - Fork 0
[3] Using state in Jetpack Compose
시간이 지남에 따라 바뀔 수 있는 모든 값.
예를들어, room DB에 저장된 값, 클래스의 변수 또는 가속도계에서 읽은 기기의 값일 수도 있다.

모든 안드로이드 앱에는 위와 같은 UI 업데이트 루프가 있다.
event - 사용자 또는 프로그램 다른 부분에 의해 생성
update state - event handler는 UI 에서 사용하는 state를 변경
display state - 새로운 state를 표시하도록 UI를 업데이트
단순하게 Activity에서 state를 저장하는 UI를 만들었다고 가정하자.
이렇게 될 경우 여러가지 문제점이 발생된다.
테스트 - UI의 state가 Views와 얽혀있기 때문에 테스트하기 어려움
부분 상태 업데이트 - event에 대한 응답으로 state의 일부를 업데이트하는 것을 잊기 쉬움
부분 UI 업데이트 - state 변경 후에 UI를 수동적으로 업데이트 하기 때문에 이것 또한 잊기 쉬움
코드 복잡성 - 말 그대로 디버깅하기 복잡함
따라서, ViewModel을 활용해야 한다.
ViewModel에서 state는 LiveData로 표시한다.
ViewModel에서 특정 UI에 동작에 따라서 LiveData의 value가 달라지고 이를 observing 하고 있는 Activity가 UI를 업데이트하는 방식
UI 업데이트 루프를 빗대어 보았을 때 ViewModel이 어떻게 event 및 state와 맞는지(fit) 알 수 있다.
event - 특정 UI가 동작할 때 호출
update state - event에 따라 LiveData를 update 함
display state - LiveData의 변경에 따른 observer 호출
이러한 방식으로 코드를 구성하면 ViewModel을 향해 "위로" 흐르는 event를 생각할 수 있다.
그리고, state가 업데이트 되면 "아래로" 흐른다. (flow)

이러한 패턴을 "단방향 데이터 흐름 사용(unidirectional data flow)" 이라고 한다.
몇 가지 이점이 있는데,
테스트 가능성 - ViewModel 및 Activity 각각 테스트 하기 더 쉬움.
상태 캡슐화 - state는 오직 ViewModel에서만 업데이트 할 수 있으므로 UI가 복잡해져도 버그의 발생 가능성 적어짐.
UI 일관성 - LiveData 라는 data holder class를 사용하여 state가 업데이트 되는 동시에 UI에 반영
state를 직접 변경할 수 없는 composable
구성 요소를 stateless 하게 만드는 패턴
시간이 지남에 따라 변경될 수 있는 'piece of state'를 소유하는 composable
LocalContentColor는 아이콘 및 타이포그래피와 같은 콘텐츠에 대해 선호하는 색상을 제공.
배경을 그리는 Surface와 같은 composable에 의해 변경됨.
데이터가 변경될 때 트리를 업데이트하기 위해 동일한 composable을 다시 실행하는 프로세스
화면을 구성하고 recomposition이 일어날 때 난수를 발생시키는 로직이 존재한다면 계속해서 해당 컴포넌트의 값이 바뀔 것이다.
그것을 방지하기위해 remember를 사용하여 계산된 값이 트리에 저장되도록 한다.
remember call 은 두 가지의 부분으로 구성되어 있다.
- key argument - 메모리가 사용하는 'key', 괄호 안에 전달되는 부분
- calculation - lambda 부분. 기억할 새 값은 계산하는 로직을 넣는다.
처음 구성될 때 calculation을 실행하고 계속해서 남아있다고 생각하면 된다.
| composable은 recomposition을 지원하기 위해 멱등해야한다.
composable에 메모리를 추가할 때 항상 "일부 호출자가 이것을 제어하기를 합리적으로 원하나?" 라는 질문을 던져야 한다.
대답이 yes면 매개변수를 만들어야하고 no면 함수 안의 로컬 변수로 유지하면 된다.
remember는 composition에 값을 저장하고 호출된 composable이 제거되면 해당 값을 잃어버린다.
이를 'state hoisting'을 활용하여 해결 할 수 있다.