[Compose] Recomposition 데이터 유지

Choi Sang Rok·2022년 2월 25일
0

compose

목록 보기
4/5
post-thumbnail

Compose에서는 데이터의 상태가 변경되었을 때, setContent가 다시 호출된다. 이를 Recomposition이라고 하는데, 따로 데이터를 저장해 두지 않는다면, Recomposition 되었을 때 데이터가 초기화 되어버린다.


💡 Compose 용어 설명

  • Composition : Jetpack Compose가 Composable을 실행할 때 빌드한 UI에 관한 설명
  • Initial Composition : 처음 Composable을 실행하여 Composition을 생성
  • Recomposition(재구성) : 데이터가 변경될 때 Composition을 업데이트 하기 위해 Composable을 다시 실행하는 것

Compose 에서는, 명령형 기반 뷰와는 달리, 데이터가 변경되면 상태를 명시적으로 알려줘야 한다.

ex) TextField에서 onValueChange를 정의해줘야 입력한 문자가 뷰에 표시된다.

본 포스팅에서는, Compose에서 데이터 변경이 발생하여 Recomposition 되었을 때, 데이터를 유지시키기 위한 방법으로 어떤 것이 있는지 알아보려고 한다.

1) remember 사용

setContent{
		val data =remember{mutableStateOf("Hello")}
		Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ){
				Text(text = data.value,
            		fontSize = 30.sp)
				Button(onClick ={
						data.value = "world"
				}){
					Text("변경")
				}
    }

}

MutableStateOf은, Observable한 MutableState를 생성하고, 런타임 시 Compose에 통합되는 Observable 유형이다.

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

Composable은 Observable하기 때문에,
value를 관찰하고 있다가 value가 변경되면 이를 감지하고 Recomposition이 예약된다.

MutableState를 remember라는 composable을 이용하여 변수를 선언하게 되면 initial composition에서 메모리에 저장되어 Recomposition 때 값을 반환받아 사용할 수 있다. 또한 값이 변경되어 ReComposition 할 때 마다 값을 저장할 수도 있다.

하지만, 화면이 회전되는 경우 Activity가 재 시작하기 때문에, 다시 그려지게 되면 remember로도 값이 유지되지 않는다. 이 때는 rememberSaveable을 사용하면 된다.

2) 기존의 ViewModel 사용

💡 ViewModel이란 ? AAC(Android Architecture Components) 중 하나로 UI 관련 데이터를 저장하고 관리해 주는 역할을 한다.

  • 액티비티와 생명주기를 동일하게 가져가기 때문에 remember 사용하지 않아도 데이터를 유지할 수 있다.
  • UI와 컨트롤러가 분리되어, 관심사 분리를 통한 코드의 유지보수가 용이하다.
  • 프래그먼트 간의 데이터 공유가 쉬워진다.
class MainActivity : ComponentActivity() {
    private val viewModel byviewModels<MainViewModel>()
		...
		setContent {
            Column(
                ...
            ){
                Text(text = viewModel.data.value,
                    fontSize = 30.sp)
                Button(onClick = {
                    viewModel.data.value = "world"
                }) {
                    Text("변경")
                }
            }

        }
class MainViewModel : ViewModel(){
    private val data = mutableStateOf("Hello")
}

3) Compose ViewModel 사용

이번에는 Compose에서 제공하는 ViewModel을 사용한다. setContent 내에서 사용할 수 있다.

위의 2번에서 ViewModel을 사용해 데이터 유지를 할 수 있었으나, ViewModel의 멤버 변수를 조작한다는 문제가 발생한다.

따라서, 본 데이터를 private 으로 선언하고 Compose에서 추적할 수 있는 State형의 데이터를 하나 생성하여, Getter 처럼 사용할 수 있게 한다.

또한, changeValue 라는 메서드를 만들어서 View에서는 값이 바뀌는 내부 동작에 대해서는 몰라야 하는 관심사 분리를 만족한다.

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
				setContent{
				val viewModel =viewModel<MainViewModel>()
				Column(
                ...
            ){
						Text(text = viewModel.data.value,
                    fontSize = 30.sp)
						Button(onClick ={
								viewModel.changeValue()
						}){
								Text("변경")
						}
        }
		}
}
class MainViewModel : ViewModel(){
    private val _data =mutableStateOf("Hello")
    val data : State<String> = _data
    fun changeValue(){
        _data.value = "world"
    }
}

[출처] https://growup-lee.tistory.com/entry/Android-Compose-State-관리
https://www.charlezz.com/?p=45464

profile
android_developer

2개의 댓글

comment-user-thumbnail
2022년 2월 25일

제 머릿속에 데이터를 저장해두지 않아서 항상 데이터 초기화가 되는걸가요?ㅠ

답글 달기
comment-user-thumbnail
2022년 10월 28일

좋은 글 감사합니다~

답글 달기