React路由器重定向导致useEffect触发两次
React router redirection causes useEffect to trigger twice
我的路线定义如下:
<Route path={`list`} element={<ListPage />}>
<Route path={`sidePanel1`} element={<SidePanel1 />} />
<Route path={`sidePanel2`} element={<SidePanel2 />} />
<Route index element={<Navigate to={`sidePanel1`} replace />}/>
</Route>
因此,当输入 /list
时,它将被重定向到 /list/sidePanel1
。
在 ListPage
组件中我有这个:
const ListPage = (): JSX.Element => {
const [data, setData] = useState<ListDto[]>([]);
const location = useLocation();
useEffect(() => {
getList()
.then(response => {
setData(response.data);
})
.catch(() => {
setIsLoading(false);
});
}, [location]);
return (
<ListTable data={data}/>
<SidePanelStyles>
<Outlet />
</SidePanelStyles>
);
};
所以,我的问题是,每当我键入 /list/
时,useEffect 都会触发,因为位置已更改,然后在重定向到 /list/sidePanel1
.[=17 时会第二次触发=]
我希望它仅在我被重定向后触发。
我该如何解决这个问题?
与其重定向和渲染两次,不如在索引路由上也渲染 SidePanel1
组件。
示例:
<Route path="list" element={<ListPage />}>
<Route index element={<SidePanel1 />} />
<Route path="sidePanel1" element={<SidePanel1 />} />
<Route path="sidePanel2" element={<SidePanel2 />} />
</Route>
一个 general-purpose 仅对快速更改序列中的最后更改做出反应的解决方案是使用“去抖动”。
即触发效果和调用 getList
之间的延迟,因此如果在延迟完成之前再次触发效果,挂起的调用将被取消。
function useDebouncedEffect(delay, effect, triggerParams) {
useEffect(() => {
const timeout = setTimeout(f, delay)
return () => clearTimeout(timeout)
}, triggerParams)
}
useDebouncedEffect(300, () => {
getList()
.then(response => {
setData(response.data);
})
.catch(() => {
setIsLoading(false);
});
}, [location]);
我的路线定义如下:
<Route path={`list`} element={<ListPage />}>
<Route path={`sidePanel1`} element={<SidePanel1 />} />
<Route path={`sidePanel2`} element={<SidePanel2 />} />
<Route index element={<Navigate to={`sidePanel1`} replace />}/>
</Route>
因此,当输入 /list
时,它将被重定向到 /list/sidePanel1
。
在 ListPage
组件中我有这个:
const ListPage = (): JSX.Element => {
const [data, setData] = useState<ListDto[]>([]);
const location = useLocation();
useEffect(() => {
getList()
.then(response => {
setData(response.data);
})
.catch(() => {
setIsLoading(false);
});
}, [location]);
return (
<ListTable data={data}/>
<SidePanelStyles>
<Outlet />
</SidePanelStyles>
);
};
所以,我的问题是,每当我键入 /list/
时,useEffect 都会触发,因为位置已更改,然后在重定向到 /list/sidePanel1
.[=17 时会第二次触发=]
我希望它仅在我被重定向后触发。
我该如何解决这个问题?
与其重定向和渲染两次,不如在索引路由上也渲染 SidePanel1
组件。
示例:
<Route path="list" element={<ListPage />}>
<Route index element={<SidePanel1 />} />
<Route path="sidePanel1" element={<SidePanel1 />} />
<Route path="sidePanel2" element={<SidePanel2 />} />
</Route>
一个 general-purpose 仅对快速更改序列中的最后更改做出反应的解决方案是使用“去抖动”。
即触发效果和调用 getList
之间的延迟,因此如果在延迟完成之前再次触发效果,挂起的调用将被取消。
function useDebouncedEffect(delay, effect, triggerParams) {
useEffect(() => {
const timeout = setTimeout(f, delay)
return () => clearTimeout(timeout)
}, triggerParams)
}
useDebouncedEffect(300, () => {
getList()
.then(response => {
setData(response.data);
})
.catch(() => {
setIsLoading(false);
});
}, [location]);