Why redux store doesn't receive an update from immer

64 Views Asked by At
  1. Combining reducers
export default (injectedReducers = {}) => {
  return combineReducers({
    ...injectedReducers,
    memoizedStamps: memoizedStampsReducer, // <-- need to write here
  });
};
  1. Writing an action
const mapDispatch = (dispatch) => ({
  addStamp: (payload) =>
    dispatch({
      type: ADD_STAMP,
      payload,
    }),
});
  1. Writing the reducer
export const initialState = [];

const memoizedStampsReducer = produce((draft, action) => {
  const { type, payload } = action;

  switch (type) {
    case ADD_STAMP:
      draft.push(payload);
  }
}, initialState);

export default memoizedStampsReducer;
  1. Using in a react hook
const useMemoizedStamps = () => {
  const [memStamps, dispatch] = useImmerReducer(reducer, initialState);
  const { addStamp } = mapDispatch(dispatch);

  useEffect(() => {
    addStamp({ body: 'body', coords: 'coords' });
  }, []);

  console.log(memStamps); // <-- gives [{ body: 'body', coords: 'coords' }] all good here
  
  return null;
};

export default useMemoizedStamps;

But it gets never saved into injected reducer "memoizedStamps". The array is always empty. It works perfectly will with connect(null, mapDispatchToProps), but can't use connect() in my custom hook.

What do I do wrong? What is the answer here?

--- UPD 1 --- @phry, like so?

const useMemoizedStamps = (response = null, error = null) => {
  const dispatch = useDispatch();
  const [memStamps] = useImmerReducer(reducer, initialState);
  const { addStamp } = mapDispatch(dispatch);

  useEffect(() => {
    addStamp({ body: 'body', coords: 'coords' });
  }, []);

  console.log(memStamps);

  return null;
};

And now if I need them to be local, I need to use immer's dispatcher? Any way to merge these two dispatchers? P.S. this dispatcher really saved it to global state.

1

There are 1 best solutions below

5
On BEST ANSWER

Rereading this, I think you just have a misconception.

Stuff is never "saved into a reducer". A reducer only manages how state changes.

In Redux, it would be "saved into the store", but for that you would have to actually use a store. useImmerReducer has nothing to do with Redux though - it is just a version of useReducer, which like useState just manages isolated component-local state with a reducer. This state will not be shared with other components.

If you want to use Redux (and use it with immer), please look into the official Redux Toolkit, which already comes with immer integrated. It is taught by the official Redux tutorial.