简体   繁体   中英

Structuring the store in Redux

Is there a way to structure const reducer = (state = initialState, action) in such a manner that the method isn't bloated by a bunch of switch cases?

My idea was to put related actions in arrays and check them with Array.prototype.includes() when handling an action.

I would then extract the switch cases that correlate to specific actions in new methods (for example the List component would have LIST_ADD , LIST_REMOVE etc.) and call those methods instead of just running through 100 cases in the const reducer = (state = initialState, action) method.

That would tax performance but it would be at least structured.

Any better ideas?

The offical Redux docs provide this very handy reducer creator:

function createReducer(initialState, handlers) {
  return function reducer(state = initialState, action) {
    if (handlers.hasOwnProperty(action.type)) {
      return handlers[action.type](state, action)
    } else {
      return state
    }
  }
}

which lets you create your reducer as follows:

const reducer = createReducer(initialState, {
  [actionType.ACTION1]: specificActionReducer1,
  [actionType.ACTION2]: specificActionReducer2,
}

No switch statements!

I use a library called reduxsauce which removes the need for large switch statements.

https://github.com/infinitered/reduxsauce

Instead it binds actions to methods with this syntax:

export const INITIAL_STATE = {
    values: {},
}

export const reducerFunction = (state, action) => {
    const values = action.value;

    return {
        ...state,
        values,
    };
};

// map the action types to the reducer functions
export const HANDLERS = {
    [Type.ACTION_NAME]: reducerFunction,
    ...
}

// call createReducer to magically tie it all together
export default createReducer(INITIAL_STATE, HANDLERS);

You could try redux-named-reducers for this as well. Allows you to compose reducers like so:

moduleA.reduce(SOME_ACTION, action => ({ state1: action.payload }))
moduleA.reduce(SOME_OTHER_ACTION, { state2: "constant" })

It has the added benefit of being able to access the reducer state anywhere, like in mapDispatchToProps for example:

const mapDispatchToProps = dispatch => {
  return {
    onClick: () => {
      dispatch(someAction(getState(moduleA.state1)));
    }
  };
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM