当 URL 参数更改时,React 路由器 6 永远不会卸载组件

Bay*_*och 7 reactjs react-router-dom

我们的 React Router v6 遇到了问题。当URL参数改变时,它已经在使用挂载组件了。切勿拆卸和安装该组件。

生成的代码示例 - 如果在链接 1 和链接 2 之间切换(url 参数 (id) 更改),则链接组件永远不会卸载和安装: https: //stackblitz.com/edit/github-agqlf5-gohmbu ?file=src/routes /link.jsx

那么我们如何让它在url参数变化时卸载并挂载组件呢?

Dre*_*ese 12

这是设计使然。如果你看一下组件的Route渲染Invoices

<Route path="link/:id" element={<Invoices />} />
Run Code Online (Sandbox Code Playgroud)

这里没有任何东西可以导致(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>
  );
}
Run Code Online (Sandbox Code Playgroud)

如果您确实想重新挂载路由组件,则创建一个包装器组件来读取id路由路径参数并在路由组件上设置 React 键。它将InvoicesWrapper保持挂载状态,但当id路由参数更新时Invoices,组件将重新挂载,因为它有一个新的 React key。

例子:

const InvoicesWrapper = () => {
  const { id } = useParams();

  return <Invoices key={id} />
};
Run Code Online (Sandbox Code Playgroud)

...

...
<Route path="link/:id" element={<InvoicesWrapper />} />
...
Run Code Online (Sandbox Code Playgroud)

  • 你节省了几个小时的谷歌搜索时间!!!! (2认同)