여기까지 오셨다면 이제 여러분들은 Reducer를 통해 Store를 생성해 View에 출력하는 방법을 모두 익히신겁니다. 하지만 이전보다 앱이 복잡해지고 규모가 커진다면 하나의 Reducer에서 상태관리를 하기에는 힘이 들기 마련입니다. 이럴 땐 Reducer를 특정 작업을 수행하도록 작게 나눌 수 있습니다.

<aside> 💡 MultiStore는 다음과 같은 강점을 가집니다.

  1. 자식 state의 부재를 UI에서 우아하게 처리할 수 있습니다.

  2. 작게 나눈 자식 Reducer는 독립적으로 작동하고 관리될 수 있습니다.

  3. 특정 부분만 업데이트하고 싶을 때 해당 부분의 작은 store를 통해 성능을 최적화 할 수 있습니다.

</aside>

MultiStore에서는 부모가 자식의 State를 보유하고 있으며 자식 State가 optional일때, 배열일 때, enum일 때 Reducer를 결합하고 이를 View에 출력하는 방법을 소개합니다.


7.1 ifLet

즉, 부모의 기능이 자식 State를 Optional로 가지고 있는 경우 사용할 수 있습니다.

다음 부모가 optional한 자식의 State를 보유하고 있으며, 부모의 Reducer에 ifLet을 달아 자식의 Action을 감지하고 있다가 자식의 State가 non optional일 때 자식의 Reducer를 실행하는 간단한 예제입니다.

struct Parent: Reducer {
	struct State {
	  var child: Child.State?
       /* code */
  }
  enum Action {
    case child(Child.Action)
       /* code */
  }

	var body: some Reducer<State, Action> {
     Reduce { state, action in
     }
     .ifLet(\\.child, action: /Action.child) {
       Child()
     }
  }
}

7.1.1 ifLet 생성자 살펴보기

@warn_unqualified_access func ifLet<WrappedState, WrappedAction, Wrapped>(
    _ toWrappedState: WritableKeyPath<Self.State, WrappedState?>,
    action toWrappedAction: CasePath<Self.Action, WrappedAction>, 
    @ReducerBuilder<WrappedState, WrappedAction> 
    then wrapped: () -> Wrapped,
    fileID: StaticString = #fileID,
    line: UInt = #line
) -> _IfLetReducer<Self, Wrapped> 
    where WrappedState == Wrapped.State, 
          WrappedAction == Wrapped.Action, 
					Wrapped : Reducer

매개변수

반환값 (_IfLetReducer<Self, Wrapped>)