在useEffect中使用React Context Dispatch时获得无限循环

时间:2020-06-18 22:45:04

标签: javascript reactjs redux

我正在研究一个项目,并创建了一个应该存储我的项目数据的上下文。我在useEffect的组件中包含了上下文调度,该组件应该将数据对象传递给上下文,但是我遇到了一个无限循环的问题。我完全简化了结构,但仍然无法弄清问题所在。我粘贴了下面的代码。有人知道我可能做错了吗?

// 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]);
    .
    .
    .

1 个答案:

答案 0 :(得分:1)

我认为您之所以会这样,是因为useEffect在第一次渲染期间被调用,它执行dispatch,该调用调用您的reducer并返回一个新对象{ dataContextInitialState }

新对象将传递给您的组件,useEffect检查dataContext对象是否与上一个渲染对象相同,但是由于它是一个新对象,因此有所不同,因此它会重新执行useEffect,您就会看到循环。

可能的解决方案

根据我对这段代码的理解

const dataContextInitialState = { test: 1 };

case "update":
  return {
    dataContextInitialState,
  };

您的状态变为:

{
  dataContextInitialState: {
    test: 1
  }
}

我猜想您想要的是具有一个键名为test的对象的状态,您可以尝试像这样修改代码:

case "update":
  return dataContextInitialState;