'I have built a global state redux like pattern with context and hooks. Is there a way to combine reducers?

I've built a global state provider context, and a reducer with the useReducer Hook. I'm realizing that combining multiple reducers like I would in redux is problematic. Is there a good way to do this? I have seen people importing combineReducers from redux itself, and that seems like it kind of defeats the point. Does anyone have any insight on this?



Solution 1:[1]

Not sure this is what you're looking for, but I have used something like below to combine multiple reducers. It actually reduces the reducers. Not actually like redux combineReducers with key/value.

const reduceReducers = (...reducers) => (prevState, value, ...args) =>
  reducers.reduce(
    (newState, reducer) => reducer(newState, value, ...args),
    prevState
  );

I would be used like:

function reducerA(state, action) {
  switch (action.type) {
    case "increment":
      return { ...state, count: state.count + 1 };
    case "decrement":
      return { ...state, count: state.count - 1 };
    default:
      return state;
  }
}

function reducerB(state, action) {
  switch (action.type) {
    case "double":
      return { ...state, count: state.count * 2 };
    case "halve":
      return { ...state, count: state.count / 2 };
    default:
      return state;
  }
}

export default reduceReducers(reducerA, reducerB);

Then the Component:

import reducers from "./reducers";

function Counter({ initialState = { count: 1 } }) {
  const [state, dispatch] = useReducer(reducers, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({ type: "increment" })}>+</button>
      <button onClick={() => dispatch({ type: "decrement" })}>-</button>
      <button onClick={() => dispatch({ type: "double" })}>x2</button>
      <button onClick={() => dispatch({ type: "halve" })}>/2</button>
    </>
  );
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Corey