如何使用 React 的 useReducer、useContext 和 useEffect 防止无限循环



我目前正试图找出如何避免在上下文提供程序中包装我的应用程序(从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的完整示例。

问题的根源在于

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

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

你需要这样改变:

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

引用自react router文档:

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

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

相关内容

  • 没有找到相关文章

最新更新