首页 > 解决方案 > 在 useEffect 中使用 React Context Dispatch 时出现无限循环

问题描述

我正在处理一个项目并创建了一个应该存储我的项目数据的上下文。我将上下文调度包含在一个组件中的 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]);
    .
    .
    .

标签: javascriptreactjsredux

解决方案


我认为发生这种情况是因为useEffect在第一次渲染期间调用了它,它执行dispatch调用你的 reducer 并返回一个新的 object { dataContextInitialState }

新对象被传递给您的组件,useEffect检查dataContext对象是否与先前渲染中的对象相同,但它不同,因为它是一个新对象,因此它重新执行useEffect并且您有循环。

一个可能的解决方案

根据我对这段代码的理解

const dataContextInitialState = { test: 1 };

case "update":
  return {
    dataContextInitialState,
  };

你的状态变成了这样:

{
  dataContextInitialState: {
    test: 1
  }
}

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

case "update":
  return dataContextInitialState;


推荐阅读