简体   繁体   中英

Getting infinite loop when using React Context Dispatch in useEffect

I'm working on a project and created a context that is supposed to store my projects data. I included the context dispatch inside of a useEffect in a component which is supposed to pass the data object to the context but I am running into an issue where I am an infinite loop. I completely simplified the structure and I still can't figure out what my problem is. I pasted the code below. Does anyone know what I could be doing wrong?

// DataContext.js
import React, { useReducer } from "react";

export const DataContext = React.createContext();

const dataContextInitialState = { test: 1 };

const dataContextReducer = (state, action) => {
  switch (action.type) {
    case "update":
      console.log(state);
      return {
        ...state,
        action.value,
      };

    default:
      return dataContextInitialState;
  }
};

export const DataContextProvider = ({ children }) => {
  const [state, dispatch] = useReducer(
    dataContextReducer,
    dataContextInitialState
  );

  return (
    <DataContext.Provider
      value={{
        state,
        dispatch,
      }}
    >
      {children}
    </DataContext.Provider>
  );
};

// Component that is accessing context

    .
    .
    .
  useEffect(() => {
    dataContext.dispatch({
      type: "update",
    });
  }, [dataContext]);
    .
    .
    .

I think this happens because the useEffect gets called during the first render, it executes dispatch that calls your reducer which returns a new object { dataContextInitialState } .

The new obect is passed down to your component, useEffect checks if the dataContext object is the same as in the previous render, but it is different because it's a new object so it re-executes the useEffect and you have the loop.

A possible solution

From my understanding with this piece of code

const dataContextInitialState = { test: 1 };

case "update":
  return {
    dataContextInitialState,
  };

your state becomes this:

{
  dataContextInitialState: {
    test: 1
  }
}

I guess that what you wanted was to have a state which is an object with a key names test , you can try modifying your code like this:

case "update":
  return dataContextInitialState;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM