我目前正在试图弄清楚如何将应用程序包装在Context提供程序中(从useReducer中获取值)然后通过带有useEffect钩子的子组件进行更新时避免创建无限循环。
有一个问题here on 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 (...)
我可能缺少明显的东西,但是任何指针都可以帮助遇到相同问题的其他人。
答案 0 :(得分:2)
问题的根源在这里
<Route path="/page1" component={() => <Page1 />} />
当您将嵌入式箭头功能作为组件传递时,基本上是为每个渲染创建新组件,并强制Route
完全重新安装此零件。发生这种情况时,useEffect
会再次被调用,依此类推。
您需要像这样更改它:
<Route path="/page1"><Page1 /></Route>
// or
<Route path="/page1" component={Page1} />
react-router文档的引用:
当您使用组件(而不是下面的渲染器或子组件)时,路由器会使用React.createElement从给定的组件中创建一个新的React元素。这意味着,如果您向组件prop提供内联函数,则将在每个渲染中创建一个新组件。这将导致现有组件的卸载和新组件的安装,而不仅仅是更新现有组件。当使用内联函数进行内联渲染时,请使用render或children道具(如下)。
来源:https://reactrouter.com/web/api/Route/route-render-methods