父组件:
<Main props... >
<LinksArray />
<Outlet context={investorId}/>
</Main>
出口组件
const NewBoards: React.FC = () => {
let { boardId } = useParams();
// this does not
useEffect(() => {
console.log('ue trigger page change',boardId )
}, []);
// this triggers (because of an argument
useEffect(() => {
console.log('ue trigger page change',boardId )
}, [boardId ]);
return (
<>
{console.log('>rerender')}
<p> newBoards</p>
<p>{boardId}</p>
</>
)
}
NewBoards是一个outlet元素,我希望useEffect在ROUTE(例如boards/123到boards/345)更改上触发,而不传递boardId,但是useEffect不会触发地址更改,除非我将boardId传递给依赖数组。boardId参数没有改变
我也想知道为什么这个useEffect不触发。我在react router v6官方文档
中找不到任何相关的内容。编辑:
我还注意到状态被保存了。outlet组件(NewBoards)中的状态不会刷新到初始状态。
edit (router definition):
{
path: '/boards/',
element: authorized ? <Boards1 /> : <Login />,
children: [{
path: '/boards/:boardId',
element: authorized ? <NewBoards /> : <Login />,
}]
},
从我从你的评论中看到,你严重误解了Outlet
和嵌套的Route
组件之间发生的事情,这些组件正在呈现它们的内容,即element
prop,进入其中。
假设authorized
为真,则以下路由配置:
{
path: '/boards/',
element: authorized ? <Boards1 /> : <Login />,
children: [{
path: '/boards/:boardId',
element: authorized ? <NewBoards /> : <Login />,
}]
},
将生成以下渲染的路由:
<Routes>
...
<Route path="/boards" element={<Boards1 />}>
<Route path="/boards/:boardId" element={<NewBoards />} />
</Route>
...
</Routes>
我认为你的理解出错的地方是,当URL路径从"/boards/123"
更改为"/boards/345"
时,在"/boards"
上渲染的Boards1
组件将渲染和重新安装Outlet
。它不会。这意味着它所渲染的Outlet
除了输出当前匹配路由的结果之外,也不做任何事情。
您的第二个困惑/误解是,当URL路径从"/boards/123"
更改为"/boards/345"
时,<Route path="/boards/:boardId" element={<NewBoards />} />
将卸载并重新安装NewBoards
组件的新实例。事实也并非如此。NewBoards
组件将保持挂载并简单地进行渲染。这是react-router-dom
的优化,因为拆除和重新安装组件比简单地用一些不同的道具/上下文/等来渲染它要多得多。
使用路由路径参数的路由组件必须"监听";修改参数,如果他们需要问题side-effects
基于参数值。这就是为什么带有空依赖数组的useEffect
钩子只在挂载NewBoards
组件时运行一次(而不是每次路由更改时),而带有boardId
参数作为依赖项的useEffect
钩子在每次boardId
值更改时正确地重新运行。
const NewBoards: React.FC = () => {
const { boardId } = useParams();
// Run this when component mounts, occurs once per mounting
useEffect(() => {
console.log('ue trigger page change', boardId);
}, []);
// Run this when the `boardId` param updates
useEffect(() => {
console.log('ue trigger page change', boardId);
}, [boardId]);
// Run this each render, i.e. no dependency array at all!
useEffect(() => {
console.log('>rerender');
});
return (
<>
<p>newBoards</p>
<p>{boardId}</p>
</>
);
};