Why is not my immer reducer returning the new value even though the draft have changed?

Viewed 200

Why is not my immer reducer returning the new value even though the draft have changed inside the reducer? I am using console.log to check if my draft is changed inside the immerReducer:

// inside my component that produces the immer
function MyComponent() {
  const immerReducer = produce(reducer);
  const [state, dispatch] = useReducer(immerReducer, initialState);
  const contextValue = useMemo(() => [state, dispatch], [state, dispatch]);
  const location = useLocation();

  useEffect(() => console.log("mounted"), []); // mounted twice

  useEffect(() => {
    dispatch({ type: ACTIONS.SET_MODE, pathname: location.pathname })
  }, [location.pathname]);

  console.log(state.mode); // I can se that this returns the "old" value, the initial value

  return (
  <MyContext.Provider value={contextValue}>
    {state.mode === MODES.DELETE ? <Deleted /> : <New />
  </MyContext.Provider>
  );
}

// inside the immer reducer file
export const reducer = (draft, action) => {
  switch (action.type) {
    case ACTIONS.SET_MODE:
      if (action.pathname.endsWith(MODES.DELETE)) {
        draft.mode = MODES.DELETE;
      } else if (action.pathname.endsWith(MODES.EDIT)) {
        draft.mode = MODES.EDIT;
      } else {
        draft.mode = MODES.NEW;
      }
      console.log("draft", draft.mode); // I can see that this logs out the wanted value
      return draft;
    ...
  }
}

, and it seems like it is changed, but when the state should have been updated, the value that is returned is the old value. Can this have anything to do with a new mounting that causes the initial state? It seemes like it is mounting twice. Can that have anything to do with me having a functional component for the component holdingn the immer reducer?

All help is appreciated!

1 Answers

Possibly produce inside Component is re-producing the reducer on each render. Try changing these to

// inside my component that produces the immer
function MyComponent() {
  const immerReducer = produce(reducer); //<-- Remove it from here it is producing new reducer 
      
// inside the immer reducer file
export const reducer = (draft, action) => { //<-- Put produce here
  // export const reducer = produce(draft, action) => {} //<- Like this
      
    
Related