0

我目前正在尝试弄清楚如何避免在将我的应用程序包装在上下文提供程序中(从 useReducer 获取值)然后使用 useEffect 挂钩通过子组件更新时创建无限循环。

CodeSandbox 上有一个问题示例。

显然不在这里重新发布所有代码很难谈论这个问题,但关键点:

根:

function App() {
   const [state, dispatch] = useReducer(reducer, initialState);
   const value = { state, dispatch };

  return (
<Context.Provider value={value}>
...
</Context.Provider>

孩子:

export const Page1: FC = () => {
  const { dispatch, state } = useContext(Context);
  const { isLoading } = state;

  useEffect(() => {
    dispatch({
      type: "loading",
      payload: false
    });
  }, [dispatch]);

 return (...)

我可能遗漏了一些明显的东西,但任何指针都可以帮助遇到同样问题的其他人。

CodeSandbox 上的完整示例

4

1 回答 1

3

问题的根源在这里

<Route path="/page1" component={() => <Page1 />} />

当您将内联箭头函数作为组件传递时,您基本上为每个渲染创建新组件并强制Route完全重新安装此部分。当它发生时,useEffect会再次调用,依此类推,依此类推。

你需要像这样改变它:

<Route path="/page1"><Page1 /></Route>
// or
<Route path="/page1" component={Page1} />

来自 react-router 文档的引用:

当你使用组件(而不是渲染或子,下面)时,路由器使用 React.createElement 从给定组件创建一个新的 React 元素。这意味着如果您为组件属性提供内联函数,您将在每次渲染时创建一个新组件。这会导致现有组件卸载和新组件安装,而不是仅仅更新现有组件。使用内联函数进行内联渲染时,请使用 render 或 children 道具(如下)。

来源:https ://reactrouter.com/web/api/Route/route-render-methods

于 2020-07-08T22:30:58.140 回答