본문 바로가기
Android/Kotlin

[Android] Compose State, Statefull, Stateless, State Hoisting

by DnaJ 2022. 3. 26.
반응형
반응형

 

하기 내용의 일부는 이전 포스팅에서 가지고 왔습니다.

중요하다고 생각이 되기 때문입니다.

 

https://myseong.tistory.com/46

 

Compose 와 선언형 UI

요즘 핫한? Compose 를 사용해보고 있습니다!!!! Wow!!!!! 오랜만의 포스팅이라 두서없이 작성이 되었습니다......ㅎㅎ Compose : 구성하다, 작성하다, 합성 출처 : https://en.dict.naver.com/#/search?range=all..

myseong.tistory.com

 

Compose 의 재구성

  • 구성 가능한 함수는 순서와 관계없이 실행할 수 있습니다.
  • 구성 가능한 함수는 동시에 실행할 수 있습니다.
  • 재구성은 최대한 많은 수의 구성 가능한 함수 및 람다를 건너뜁니다.
  • 재구성은 낙관적이며 취소될 수 있습니다.
  • 구성 가능한 함수는 애니메이션의 모든 프레임에서와 같은 빈도로 매우 자주 실행될 수 있습니다.

 

핵심 용어

Composition

 - JetBack Compose 가 컴포저블을 실행 할때 빌드한 UI에 관한 설정

 

Initial Composition

 - 처음 컴포저블을 실행하여 컴포지션을 만듭니다.

 

Recomposition

 - 데이터가 변경될 때 컴포지션을 업데이트 하기 위해 컴포저블을 다시 실행 하는 것을 말합니다. 

 

출처 : https://developer.android.com/jetpack/compose/mental-model#recomposition

 

Compose 이해  |  Jetpack Compose  |  Android Developers

Compose 이해 Jetpack Compose는 Android를 위한 현대적인 선언형 UI 도구 키트입니다. Compose는 프런트엔드 뷰를 명령형으로 변형하지 않고도 앱 UI를 렌더링할 수 있게 하는 선언형 API를 제공하여 앱 UI를

developer.android.com

 

=========================

 

출처 :https://developer.android.com/jetpack/compose/state#state-in-composables

 

상태 및 Jetpack Compose  |  Android Developers

상태 및 Jetpack Compose 앱의 상태는 시간이 지남에 따라 변할 수 있는 값입니다. 이는 매우 광범위한 정의로서 Room 데이터베이스부터 클래스 변수까지 모든 항목이 포함됩니다. 모든 Android 앱에서

developer.android.com

 

State

Compose에서는 State 가 변경되면 화면 재구성이 발생 됩니다.

value가 변경되면 value를 읽는 구성 가능한 함수의 리컴포지션이 예약됩니다.

interface MutableState<T> : State<T> {
    override var value: T
}

 

State 는 remember 라는 함수에 의해 Compose에서 상태를 보존 합니다.

@Composable
fun TestComposable {
   val stringState = remember { mutableStateOf("") } 
   
   val stringState = rememberSaveable { mutableStateOf("") } 
}

remember

  • Recomposition 이 발생 했을 때 state의 상태를 보존 
  • Rotate 및 폴드의 화면 접었다 폈을때 와 같은 동작에서는 State 를 보존하지 못합니다.

rememberSaveable

  • Recomposition 이 발생 했을 때 state의 상태를 보존
  • Rotate 및 폴드의 화면 접었다 폈을때 와 같은 동작에서 State 를 보존 합니다.
  • Bundle저장 할 수 있는 값저장 합니다

* remember 와 rememberSavable 은 다른 포스팅에서 조금더 자세하게 다룰 예정입니다.

 

Statefull 과 Stateless

Compose에서 중요하다고 생각하는 부분 중 한가지 입니다.

간단하지만 State관리에 중요한 부분을 차지하고 있습니다.

Stateless composable 은 Recomposition이 일어나지 않을수 있기 때문입니다.

 

Statefull

 - remember 를 사용하여 객체를 저장하는 composable

 

Stateless

 - State를 갖지 않은 Composable

 

 

State Hoisting

Compose 에서 ComposableStateless 로 만들기 위해 상태를 컴포저블의 호출자로 옮기는 패턴입니다.

상태를 관리하기 위하여 State Hoisting 패턴을 사용합니다.

상태를 한곳에서 관리를 하기 때문에 여러 이점들이 존재합니다.

 

이러한 방식으로 끌어올린 상태에는 중요한 속성이 몇 가지 있습니다.

  • 단일 소스 저장소: 상태를 복제하는 대신 옮겼기 때문에 소스 저장소가 하나만 있습니다. 버그 방지에 도움이 됩니다.
  • 캡슐화됨: 스테이트풀(Stateful) 컴포저블만 상태를 수정할 수 있습니다. 철저히 내부적 속성입니다.
  • 공유 가능함: 호이스팅한 상태를 여러 컴포저블과 공유할 수 있습니다. 다른 컴포저블에서 name을 사용하려는 경우 호이스팅을 통해 그렇게 할 수 있습니다.
  • 가로채기 가능함: 스테이트리스(Stateless) 컴포저블의 호출자는 상태를 변경하기 전에 이벤트를 무시할지 수정할지 결정할 수 있습니다.
  • 분리됨: 스테이트리스(Stateless) ExpandingCard의 상태는 어디에나 저장할 수 있습니다. 예를 들어 이제는 name을 ViewModel로 옮길 수 있습니다.

 

@Composable
fun HelloScreen() {
    var name by rememberSaveable { mutableStateOf("") }

    HelloContent(name = name, onNameChange = { name = it })
}

@Composable
fun HelloContent(name: String, onNameChange: (String) -> Unit) {
    Column(modifier = Modifier.padding(16.dp)) {
        Text(
            text = "Hello, $name",
            modifier = Modifier.padding(bottom = 8.dp),
            style = MaterialTheme.typography.h5
        )
        OutlinedTextField(
            value = name,
            onValueChange = onNameChange,
            label = { Text("Name") }
        )
    }
}

 상태를 끌어올릴 때 상태의 이동 위치를 쉽게 파악할 수 있는 세 가지 규칙이 있습니다.

  1. 상태는 적어도 그 상태를 사용하는 모든 컴포저블의 가장 낮은 공통 상위 요소로 끌어올려야 합니다(읽기).
  2. 상태는 최소한 변경될 수 있는 가장 높은 수준으로 끌어올려야 합니다(쓰기).
  3. 동일한 이벤트에 대한 응답으로 두 상태가 변경되는 경우 두 상태를 함께 끌어올려야 합니다.

 

Stateless composable 은 Recomposition이 일어나지 않을수 있습니다. 

  • state 의 변경이 없을경우 화면의 재구성이 발생하지 않습니다.
  • Stateless Composable Parameter 에 인자가 전달 되더라도 참조 하지 않으면 Recomposition 이 발생하지 않습니다
// Statefull comppsable
@Composable
fun StatefullComposable() {
  val textState = remember{ mutableState("변경되는 텍스트") }
  
  TextComposable(text)
  EmptyComposable(text)
  notComposableFunction(text)
}

// Stateless comppsable
// textState.value 변경 시 로그가 출력 됩니다.
@Composable
fun TextComposable(text: String) {
  Text(text)
  Log.d(TAG, "TextComposable")
}

// Stateless comppsable
// textState.value 변경 시  로그가 출력 되지 않습니다.
@Composable
fun EmptyComposable(text: String) {
  Log.d(TAG, "EmptyComposable")
}


// 일반 함수
// textState.value 변경 시  로그가 출력 됩니다.
fun notComposableFunction(text: String) {
  Log.d(TAG, "notComposableFunction")
}

 

 

https://myseong.tistory.com/46

 

[Android] Compose 와 선언형 UI

요즘 핫한? Compose 를 사용해보고 있습니다!!!! Wow!!!!! 오랜만의 포스팅이라 두서없이 작성이 되었습니다......ㅎㅎ Compose : 구성하다, 작성하다, 합성 출처 : https://en.dict.naver.com/#/search?range=all..

myseong.tistory.com

https://myseong.tistory.com/48

 

[Android] Compose lifecycle

Compose lifecycle https://developer.android.com/jetpack/compose/lifecycle?hl=ko 컴포저블 수명 주기  | Jetpack Compose  | Android Developers 컴포저블 수명 주기 이 페이지에서는 컴포저블의 수명 주기..

myseong.tistory.com

https://myseong.tistory.com/49

 

[Android] Compose CompositionLocal

CompositionLocal https://developer.android.com/jetpack/compose/compositionlocal?hl=ko CompositionLocal을 사용한 로컬 범위 지정 데이터  | Jetpack Compose  | Android Developers CompositionLocal을 사..

myseong.tistory.com

 

 

반응형

댓글