What is the main difference between these two Reducer?

Can some one please explain with example when, where and why do i use these two different Reducers?

struct AddToCartDomain: ReducerProtocol {
        struct State: Equatable {...}
        enum Action: Equatable {
            case viewDidLoad
        }
        
        var body: some ReducerProtocol<State, Action> {
            Reduce { state, action in
                switch action {
                case .viewDidLoad:
                    return .none
                }
            }
        }

        // when do i use this two Reducer's? 👆👇 

        func reduce(into state: inout State, action: Action) -> EffectTask<Action> {
            switch action {
            case .viewDidLoad:
                return .none
            }
        }
}

Hi @amith156, as written there is no difference. If AddToCartDomain does not need to compose in the logic from other reducers, then you can just implement reduce(into:action) and leave off body. But if later you break this reducer up into smaller pieces, then the body property will be handy.

1 Like

Thank you @mbrandonw

I have few more questions

  1. The return type of the "second" Reducer is EffectTask<Action>, why is the "first" Reducer of type some ReducerProtocol<State, Action> rather then EffectTask<Action> ?

  2. What is the main difference between EffectTask and Effect?

The reduce(into:action:) style of defining a reducer is the more "primitive" version that involves implementing all of the logic for the feature directly in that method. You have to do two things: mutate the state to represent how the feature evolves when an action is received, and return an EffectTask to represent what effects should be executed and how they feed actions back into the system.

The body style of defining a reducer is more "high level". You don't directly perform any of the mutation or effect logic in body and instead you compose many other reducers together, similar to how SwiftUI views work.

There is a lot more information on these topics in the docs (like the docs for ReducerProtocol), so I recommending reading them.

EffectTask is a typealias for Effect right now, so they are equivalent, and Effect is deprecated so you should not be using it. We are in the middle of a multistage refactor of this type in order for it to have a single generic instead of two, and we are trying to minimize how much breakage is caused in people's code.

If look at the docs for Effect you will see that it is deprecated and there is a link to a discussion where we lay out our road map for changing things.