https://velog.io/@evergreen_tree/AndroidMVI-2.-MVI%EC%9D%98-Purecycle 에서 이어집니다.
항상 모든 흐름이 Pure cycle로 이루어 질 순 없습니다.
앱은 외부세계의 상태를 변화시켜야 하는 상황이 발생하기도 하고, 외부 세계로부터 상태가 변화될 수 있습니다.
예를들어, Composable 함수 같은 경우, compose 내의 State가 변경되면 이를 통해 재 호출 되어 Recomposition 되는 형태로만 존재해야 합니다.
@Composable
fun ExampleButton{
SideEffect{
systemUiController.setStatusBarColor(
color = BackgroundColor
)
}
}
하지만 위 코드처럼, systemUiController의 상태를 변경시켜야 하는, 즉 SideEffect를 발생시켜야 하는 상황에 직면하기도 합니다.
SideEffect()는, Composition이 성공적으로 완료되었을 때 부수 효과를 예약하는 함수로 Compose에서 부수 효과를 처리하기 위한 방법 중 하나입니다.
Compose 얘기는 여기하지 하고, 안드로이드의 Orbit FrameWork 이용하여 MVI의 SideEffect Cycle을 구현해 보겠습니다.
SideEffect Cycle은 기존 Pure Cycle에 SideEffect를 추가한 것입니다.
intent()
를 사용하여 새로운 상태를 생성함과 동시에 부수 효과를 실행하고, 인텐트로 결과를 내보내거나 아무 일도 일어나지 않습니다.
버튼을 클릭했을 때 토스트 메시지를 출력하는 간단한 앱을 MVI + Compose로 만들어 보겠습니다.
data class CalculatorState (
val total: Int = 0
)
sealed class CalculatorSideEffect{
data class Toast(val text: String): CalculatorSideEffect()
}
함수형 프로그래밍인 자바스크립트에서도, Side Effect는 존재합니다. 함수가 일관된 결과를 보장하지 못하거나, 함수 외부 어디든지 조금이라도 영향을 주는 경우에 발생하게 됩니다.
class CalculatorViewModel: ViewModel(), ContainerHost<CalculatorState, CalculatorSideEffect> {
override val container =container<CalculatorState,CalculatorSideEffect>(CalculatorState())
fun add(number :Int) = intent{//intent - 앱의 상태를 변화시키려는 의도
postSideEffect(CalculatorSideEffect.Toast("Adding $number to ${state.total}!"))
reduce{
state.copy(total = state.total + number)
}
}
}
ViewModel 에서 State와 SideEffect를 가지고 container를 재정의합니다.
add라는 메소드를 intent에 담고 Toast라는 SideEffect에 Toast에 들어갈 메시지를 담아 SideEffect를 보냅니다.
연산된 결과를 reduce를 통해 새로운 state를 만들어 내는 과정은 Pure Cycle과 같습니다. 단지 postSideEffect가 추가 되었을 뿐입니다.
@Composable
fun TestPage(
viewModel: CalculatorViewModel,
)
...
LaunchedEffect(viewModel){
viewModel.container.sideEffectFlow.collect{
when(it){
is CalculatorSideEffect.Toast -> Toast.makeText(context,it.text, Toast.LENGTH_SHORT).show()
}
}
}
...
🙋♂️이상으로 MVI 시리즈를 마치겠습니다. 감사합니다.
참고 자료
https://sungbin.land/아직도-mvvm-이젠-mvi-시대-319990c7d60
https://medium.com/@kimdohun0104/mvi-패턴에-대한-고찰-이유와-방법-그리고-한계-767cc9973c98
https://dev.to/kaleidot725/implementaing-jetpack-compose-orbit-mvi-3gea
아싸 1빠