React Router 6在URL参数改变时不会卸载组件。

5
我们在使用React Router v6时遇到了问题。当URL参数改变时,它已经在使用挂载组件,从未卸载和重新挂载该组件。
代码示例 - 如果在链接1和链接2之间切换(url参数(id)更改),则Link组件永远不会卸载和重新挂载: https://stackblitz.com/edit/github-agqlf5-gohmbu?file=src/routes/link.jsx 那么我们如何在URL参数更改时将其卸载和重新挂载组件呢?

你是在说App组件没有被卸载吗? - Mridul Gupta
不,Link组件在url参数(id)更改时永远不会卸载和挂载。 - Laakal
所以你不想一直有链接组件,你想回到不渲染链接组件的主页? - Mridul Gupta
如果您点击链接1,则链接组件将被挂载。然后,如果单击链接2,则链接组件不会卸载,而是仅使用旧的已挂载链接组件进行挂载。 - Laakal
1个回答

10

这是设计上的考虑。如果您查看渲染Invoices组件的Route

<Route path="link/:id" element={<Invoices />} />

这里没有任何东西会导致 (a) Route 重新挂载,以及 (b) 路由组件 Invoices 重新挂载。如果路由路径更新,它只会触发路由组件的重新渲染,实际上只有路由上下文中的值发生了更改。将其视为更新 props 触发组件重新渲染,而不是重新挂载。

如果路由组件需要 "监听" 并响应路由参数的更改,则应使用 useEffect 钩子来执行任何副作用。

例如:

import { Outlet, useParams } from 'react-router-dom';

export default function Invoices() {
  const { id } = useParams();

  React.useEffect(() => {
    console.log('mount');
    return () => console.log('unmount');
  }, []);

  React.useEffect(() => {
    console.log("Route parameter changed", { id });
  }, [id]);

  return (
    <div style={{ display: 'flex', paddingTop: '1rem' }}>
      <nav>Invoice ID: {id}</nav>
      <Outlet />
    </div>
  );
}

如果您真的想重新挂载路由组件,则创建一个包装器组件,读取id路由路径参数并在路由组件上设置一个React key。 InvoicesWrapper将保持挂载状态,但当id路由参数更新时,Invoices组件将重新挂载,因为它具有新的React key。
例如:
const InvoicesWrapper = () => {
  const { id } = useParams();

  return <Invoices key={id} />
};

...

...
<Route path="link/:id" element={<InvoicesWrapper />} />
...

你节省了好几个小时的谷歌搜索!!!! - gkd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接