
Declarative class-based reducers for redux and NGRX - zzzakzakzakzak
https://itnext.io/reducer-organization-taking-a-step-further-4aba7af755d6
======
acemarke
I'll quote the comment I made when this was posted over in /r/javascript a
month ago [0]:

So, as a Redux maintainer...

I completely do _not_ see the point of trying to write reducers as classes.

A reducer is a pure function. There shouldn't be any use of `this` inside.
Therefore, it doesn't need to be defined as a class instance method. Some kind
of a factory function, as recommended in the docs? Sure.

Let me specifically address the points of concern about the
`createReducer`-type approach:

>\- In case of complex reducers we have to leave lots of comments describing
what this reducer does and why.

I don't see how this changes no matter where or how you define the reducer.

> \- Huge reducer maps are hard to read.

If this is truly a concern, then try defining the functions outside the lookup
table.

> \- Each reducer has only one corresponding action type. What if I want to
> run the same reducer for several actions?

Then define the functions outside the lookup table, and associate them with
multiple keys.

Going a step further beyond this, our new Redux Starter Kit package [1] has a
`createSlice` function [2] that will auto-generate action types and action
creators for reducer functions that are passed in, and _also_ allows you to
pass in reducers to handle action types that were defined elsewhere. Example:

    
    
        const counter = createSlice({
          slice: 'counter', // slice is optional, and could be blank ''
          initialState: 0,
          reducers: {
            increment: state => state + 1,
            decrement: state => state - 1,
            multiply: (state, action) => state * action.payload
          }
        })
    
        const user = createSlice({
          slice: 'user',
          initialState: { name: '', age: 20 },
          reducers: {
            setUserName: (state, action) => {
              state.name = action.payload // "mutate" the state all you want with immer
            }
          },
          extraReducers: {
            [counter.actions.increment]: (state, action) => {
              state.age += 1
            }
          }
        })
    

I'd encourage folks to try out Redux Starter Kit and see how much it can help
simplify your Redux apps.

[0]
[https://www.reddit.com/r/javascript/comments/awk2be/reducer_...](https://www.reddit.com/r/javascript/comments/awk2be/reducer_organization_taking_a_step_further/)

[1] [https://redux-starter-kit.js.org/](https://redux-starter-kit.js.org/)

[2] [https://redux-starter-kit.js.org/api/createSlice](https://redux-starter-
kit.js.org/api/createSlice)

~~~
keenondrums
How does `this` prevent any function from being a pure function? Classes could
be just a different way to organize your code. Anyway, lots of good arguments
were made for and against in that reddit discussion.
[https://www.reddit.com/r/javascript/comments/awk2be/reducer_...](https://www.reddit.com/r/javascript/comments/awk2be/reducer_organization_taking_a_step_further/)

