How to add ad-hoc reducer to top-level var body some ReducerProtocol {Scope A, ScopeB, ScopeC}

301 views Asked by At

In order to conform to the ReducerProtocol, a conforming Struct either implements reduce(into: action:) method or the var body: some ReducerProtocol computed property. How do I handle the situation where I want to add both to the top level Reducer Protocol Struct?

1

There are 1 answers

0
Small Talk On

The answer is to add a stand-alone Reducer into the body var, at whatever level you want the relevant action to be processed. From the documentation:

Reduce is useful for injecting logic into a reducer tree without the overhead of introducing a new type that conforms to ReducerProtocol.

struct AppReducer: Reducer {
    
    enum Action {
        case childFeatureAction(ChildFeature.Action)
        case printHi
        
    }
    
    struct State {
        var helloText = "Hello World"
        var childFeature =
        ChildFeature.State()
        
    }


 var body: some Reducer<State, Action> {
        //below is the start of the stand-alone reducer. In this case it's placed above Scope calls.
//But it can be placed anywhere above or below any Scope declaration.
//Since including a `body` fulfills the ReducerProtocol requirement, do not implement the `reduce(into:)` method in this ReducerProtocol Struct
        Reduce{(state, action) -> Effect<AppReducer.Action> in
            switch action {
            case .printHi: return Effect.run { [state] send  in
                print(state.helloText)
            }
            default: return .none
            }
        }

//'regular' Scope-type builder statement
        Scope(state: \.childFeature, action: /Action.childFeatureAction) {
            ChildFeature()
        }
//etc
    }
}