[Compose] StateFlow 와 remember 에 대하여
기존 MVVM 패턴을 사용할 때 일반적으로 ViewModel 에선 LiveData 를 많이 사용하였는데
Compose 로 넘어오고 나서 각종 예제들을 보면 State 를 Flow 로써 관리하는 StateFlow 를 자주 사용합니다.
이 State 에 따라 Composable 이 어떻게 동작하는지 대략적으로 정리하고자 합니다.
State 와 remember
Compose 에서는 기본적으로 State 의 value 가 바뀌면 View 가 Update 되는데( recomposition )
Composition 이 일어나면 Composable 이 화면에 표시되면서 초기화가 진행됩니다.
예시와 함께 이해를 도와보자면..
var currentValue = mutableStateOf(0)
Text(text = currentValue.toString())
Button(onClick = { currentValue.value ++ }) {
Text(text = "Value Up!")
}
이 코드에서 버튼을 누르면 currentValue 의 State 가 변화하게 되는데(1이 증가합니다.)
그러면 Recomposition 이 일어나게되며
다시 첫 줄의 var currentValue by mutableStateOf(0) 를 통해 State의 value가 0으로 초기화되고
결과적으로 화면엔 0이 적혀있는 Text 만 남게 됩니다.
이런 상황에서 사용할 수 있는 것이 remember 블록 입니다.
remember 는 직역한 대로 블록 내부의 State 를 "기억" 하는데
State 의 value 가 recomposition 에 의해 초기화 되지 않도록 값을 기억한다고 생각하면 됩니다.
가령 위의 코드의 State 를 remember 블록으로 아래와 같이 감싸면
var currentValue by remember {
mutableStateOf(0)
}
Text(text = currentValue.toString())
Button(onClick = { currentValue ++ }) {
Text(text = "Value Up!")
}
Button 을 눌렀을 때 mutableStateOf 의 값이 0에서 1로 변화하고 recomposition 이 일어나며
이때 remember 블록 내부의 값은 "기억" 되고 있기 때문에 value 가 초기화되지 않고 원하던 결과대로 1을 보여주게 되죠
하지만 이는 하위 Composable 로 나누어서 작성된 경우 State 가 변해도 recomposition 이 일어나지 않는 경우가 있는데
이럴 때 사용할 수 있는것이 바로 rememberUpdatedState 입니다.
var currentValue by remember {
mutableStateOf(0)
}
val _currentValue by rememberUpdatedState(currentValue)
CustomText(text = _currentValue.toString())
CustomButton(onClick = { currentValue ++ }) {
Text(text = "Value Up!")
}
rememberUpdatedState 의 경우 정확히는 parameter 로 전달받은 mutableState 에 직접 값을 update 해줌으로써
하위 Composable 에서 해당 value 에 접근할 경우 변화된 점이 State 에서 반영되어 recomposition 이 일어납니다.
위 코드에서 예를 들면 CustomButton 이라는 composable 에서 CustomText 에 사용되는 State 에 변화를 준 것을 직접적으로 apply 해줌으로써 recomposition 이 일어나게해주는 것이죠.