prevState with useReducer hook in React.

ivan_jrmc

Ivan Jeremic

Posted on September 19, 2020

prevState with useReducer hook in React.

I wanted to share not only how I currently do State Management with React Context but also what I do when I need prevState, If there are any suggestions for improvement let me know.

Hope this helps some of you :)

import React, {
  createContext,
  useReducer,
  useContext,
  useEffect,
  useRef,
} from 'react';

/* ******* */
/* Reducer */
/* ******* */
function reducer(state, action) {
  switch (action.type) {
    case 'LOGIN':
      return {
        ...state,
        isLoggedIn: true,
      };

    default:
      return state;
  }
}

const StateContext = createContext({});
const DispatchContext = createContext({});
const PrevStateContext = createContext({});

const StateContainer = (Context) => {
  const context = useContext(Context);
  if (context === undefined) {
    throw new Error('Context must be used within a Provider');
  }
  return context;
};

const DispatchContainer = (Context) => {
  const context = useContext(Context);
  if (context === undefined) {
    throw new Error('Context must be used within a Provider');
  }
  return context;
};

const PrevStateContainer = (Context) => {
  const context = useContext(Context);
  if (context === undefined) {
    throw new Error('Context must be used within a Provider');
  }
  return context;
};

const AppContextProvider = (props) => {
  const { children } = props;

  const [state, dispatch] = useReducer(reducer, {
    isLoggedIn: false,
  });

  function usePrevious(value: any) {
    const ref = useRef();
    useEffect(() => {
      ref.current = value;
    });
    return ref.current;
  }

  let prev = usePrevious(state);

  return (
    <StateContext.Provider value={state}>
      <DispatchContext.Provider value={dispatch}>
        <PrevStateContext.Provider value={prev === undefined ? {} : prev}>
          {children}
        </PrevStateContext.Provider>
      </DispatchContext.Provider>
    </StateContext.Provider>
  );
};

const useAppContext = () => {
  return [
    StateContainer(StateContext),
    DispatchContainer(DispatchContext),
    PrevStateContainer(PrevStateContext),
  ];
};

export { AppContextProvider, useAppContext };
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
ivan_jrmc
Ivan Jeremic

Posted on September 19, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related