728x90

출처 : https://developer.android.com/jetpack/compose/state?hl=ko#restore-ui-state 

 

상태 및 Jetpack Compose  |  Android Developers

상태 및 Jetpack Compose 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 앱의 상태는 시간이 지남에 따라 변할 수 있는 값을 의미합니다. 이는 매우 광범위한 정

developer.android.com

 

이전글에서는 선언형 UI가 무엇인지, 재구성과 부작용이 무엇인지 간단히 살펴보았다. 

오늘은 콤포오즈 사용에 있어 빠질 수 없는 상태에 대한 이해..

 

상태(State) 

시간이 지남에 따라 변할 수 있는 값

ex) 

  • 네트워크 연결을 설정할 수 없을 때 표시되는 스낵바
  • 블로그 게시물 및 관련 댓글
  • 사용자가 클릭하면 버튼에서 재생되는 물결 애니메이션
  • 사용자가 이미지 위에 그릴 수 있는 스티커

 

상태 및 구성

Composable 을 업데이트 하려면 새 인수로 동일 컴포저블을 호출해야함

 

컴포저블의 상태(State)

컴포저블은 remeber API 를 사용해 메모리에 객체를 저장할 수 있음

초기 컴포지션 중에 값을 저장하고

리컴포지션시에 이 값을 꺼내 사용

 

MutableState<T> 형식 : 관찰가능한 유형 대표(?)

 

관찰가능한 객체를 선언하는 세가지 방법

  • val mutableState = remember { mutableStateOf(default) }
  • var value by remember { mutableStateOf(default) }
  • val (value, setValue) = remember { mutableStateOf(default) }

 

주의 : ArrayList<T>, mutableListOf() 같은 mutable 한 객체를 상태로 사용하면 관찰이 불가하여 객체 변경 시 리컴포지션이 트리거되지 않는다. State<List<T>>, listOf() 등 관찰 가능한 데이터 홀더를 사용할 것! 

 

Remember 는 재구성(recomposition)시에 값을 저장하는 역할, 구성 변경 전반에서는 값을 저장하지 못하므로 

그러한 역할이 필요할 때는 remember saveable 을 사용한다.

 

Remember saveable 에는  Bundle 에 저장될 수 있는 값 형태나, 맞춤 Saver 객체가 저장된다. 

(번들에 추가할 수 없는 데이터 유형을 사용하고 싶은 경우 @Parcelize 주석, mapSaver, ListSaver 등을 이용하여 saver 객체를 만들어 저장할 수 있다.... 김 비둘기 님 피드백)




Jetpack Compose 에서 지원되는 기타 상태 유형

 

컴포즈는 state 객체를 읽어 재구성(리컴포지션)을 수행하므로 관찰 대상 데이터들을 state로 변환해주어야한다.

 

아래 유형들을 State<T> 로 변환하는 함수가 Compose 에 내장되어있음 



Flow : CollectAsStateWithLifecycle() - Android 전용

Flow : CollectAsState

LiveData : ObserveAsState()

RxJava2 : subscribeAsState()

RxJava3 : subscribeAsState()

 

이외에 다른 유형을 컴포즈와 함께 사용하기 위해 produceState API 를 이용해 직접 확장함수를 빌드해도 된다고 한다..



스테이트풀(Stateful)과 스테이트리스(Stateless)

스테이트풀 : remember 로 객체를 저장하는 컴포저블을 스테이트풀 하다고 한다.

스테이트리스 : 내부에 state 를 갖지 않는 컴포저블(파라미터로 받아서 쓰기만..)

 

스테이트풀은 호출자가 상태를 제어,관리할 수 없다 -> 스테이트풀은 호출자가 상태를 제어,관리할 필요 없을 때 쓴다

스테이트풀한 컴포저블은 밖에서 스테이트를 제어, 관리 할 수 없으므로 재사용 가능성이 적고 테스터블하지 않다. 

 

따라서 재사용을 위한 컴포저블 개발 시 스테이트풀/ 스테이트리스 모두 노출하기도 함



상태 호이스팅 

컴포저블을 스테이스리스로 만들기위해 상태를 호출자로 옮기는(끌어올리는) 패턴

내부의 상태변수를 두개의 매개변수로 바꾼다 

  1. Value : 표시될 값
  2. Event : 값 변경을 요청하는 이벤트

 

2번 Event 는 onValueChange : (T) -> Unit 형태로 많이 쓰지만 구체적 이벤트가 어울리는 경우 람다를 이용해 정의할 수 있음

 

끌어올려진 상태의 중요한 속성

  • 단일 정보 소스 - Single Source Of Truth : 버그 방지
  • 캡슐화 : 끌어올림 받은(?) 스테이트풀 컴포저블의 내부적 속성으로 이 스테이트풀 컴포저블만 상태를 수정할 수 있음
  • 공유가능 : 호이스팅 후 스테이트풀 컴포저블 내부(하위의) 다른 컴포저블에도 값을 공유할 수 있다
  • 가로채기 가능 : 호출자가 값을 먼저 보고 무시하거나 수정하는 등 결정이 가능
  • 분리됨 : 상태를 뷰모델 등 어디든지 저장할 수 있음

 

이러한 호이스팅을 통해 UI 상태를 표시하는 컴포저블과 상태를 저장하고 변경하는 앱 부분을 분리할 수 있다.

 

상태만 mock 으로 주고 이래저래 테스트도 간편하고 좋다… 

 

 

 

 

 

 

틀린내용 댓글로 달아주시면 감사합니다

 

728x90

+ Recent posts