-
Notifications
You must be signed in to change notification settings - Fork 1
4. Reducer, SideEffectHandler
kimdohun0104 edited this page Oct 18, 2020
·
1 revision
Reducer는 다음 상태를 결정하는 중요한 역할을 담당합니다. reduce()
함수는 이전 상태와 이벤트를 파라미터로 받습니다.
다음 상태를 생성하여 Next
객체를 반환합니다. Next
객체는 다음 상태와 실행될 SideEffect(선택적)에 대한 정보를 가지고 있습니다.
class CountReducer : KindaReducer<CountState, CountEvent, CountSideEffect> {
override fun reduce(state: CountState, event: CountEvent): Next<CountState, CountSideEffect> {
return when (event) {
CountEvent.AttemptMagic -> Next(null, CountSideEffect.Magic)
CountEvent.Increase -> Next(state.copy(count = state.count + 1))
CountEvent.Decrease -> Next(state.copy(count = state.count - 1))
CountEvent.Increase1000 -> Next(
state.copy(
count = state.count + 1000,
toastEvent = Event("Increase 1000, It's magic!")
)
)
}
}
}
Kinda의 상태는 불변성을 가지기 때문에 값을 변경할 수 없습니다. 대신 코틀린 data class
의 copy()
메소드를 사용하여 값이 변경된 새로운 상태를 생성할 수 있습니다.
AttemptMagic 이벤트 같은 경우엔 다음 상태로 null
을 넘겨주는 것을 확인할 수 있습니다. AttemptMagic는 SideEffect를 실행시킬 뿐, 상태의 값이 변경되지 않습니다. Kinda는 상태가 변경될 때마다 render()
를 실행하기 때문에 이같은 상황에서 불필요한 낭비를 할 수 있습니다.
만약 새로운 상태를 생성하는 것을 원하지 않는다면, Next에 null을 넣어줄 수 있습니다.
SideEffectHandler
는 부수 효과를 프로그램의 로직에서 완전히 분리할 수 있도록 설계되었습니다.
그렇기 때문에 프로그래머는 로직에 더 집중할 수 있으며, 테스트 작성 난이도가 감소합니다.
class CountSideEffectHandler(
private val countRepository: CountRepository
) : KindaSideEffectHandler<CountState, CountEvent, CountSideEffect> {
override suspend fun handle(state: CountState, sideEffect: CountSideEffect): CountEvent {
return when (sideEffect) {
CountSideEffect.RequestCount -> { it: RequestCount ->
val result = countRepository.requestCount(it.userId)
CountEvent.SetCount(result)
}
}
}
}
CountRepository
라는 부수 효과와 관련이 깊은 의존성을 SideEffectHandler에 격리시킴으로써 프로그래머는 비즈니스 로직에 더 집중할 수 있습니다.