reactjsreact-hooksuse-reducerside-effects

use dispatch from useReducer in useEffect - React


In react I'm trying to do a GET request on first render in a useEffect and then dispatch the response to update the useReducer state.

Here is the code:

   const [{ firstTime, typeOfDev, technologies }, dispatch] = useReducer(
      typeOfDevReducer,
      initialState
   );

   useEffect(() => {
      const getTypeOfDev = async () => {
         try {
            const typeOfDev = (await axiosPrivate.get<ITypeOfDev>(`type-of-dev/get/${user!.id}`))
               .data;
            dispatch({
               type: REDUCER_ACTION_TYPE.GET_USER,
               payload: { value: typeOfDev },
            });
           ^^^^^^^^^^^^^ Here is the error
         } catch (err: any) {
            if (err.response?.status === 404)
               dispatch({ type: REDUCER_ACTION_TYPE.SET_FIRST_TIME });
         } finally {
            dispatchRedux(setObjectValueChanged(false));
         }
      };

      getTypeOfDev();
   }, [axiosPrivate, user]);

And here is the beginning of my reducer:

export default (state: IInitState, action: reducerAction): IInitState => {
   const dispatch = useAppDispatch();
   dispatch(setObjectValueChanged(true));

   switch (action.type) {
      case REDUCER_ACTION_TYPE.GET_USER: {
         console.log(action.payload);
         return { ...state, typeOfDev: { ...action.payload!.value } };
      }

But I have an error from react saying : Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks ... and also React has detected a change in the order of Hooks called by DeveloperType....

I understand that dispatch is a react hook and should not be used in a side effect but is there a work around for this issue?


Solution

  • The issue is that you are calling useAppDispatch (which by the name I'm assuming is a hook) inside the reducer function. Hooks should only be called at the root level of the render function of a component.