我刚刚将我的应用程序从 React Router Dom v5 迁移到 v6。
我发现了一个奇怪的现象。
我的应用程序的结构使得在项目和子项目之间移动的用户保持在相同的 URL (example.com/projects) 上。状态会更新以更改项目,同时保持 URL 不变。
因此,例如,用户可能从项目 A 到项目 B 再到项目 C,所有这些都停留在 /projects 的相同路线上。
在 v6 之前,Link 组件完美地处理了这个问题,包括正确处理浏览器的后退按钮。
但在 v6 中,链接组件似乎有效地合并了不同的状态。如果用户从 /home 开始,单击项目 A,然后单击项目 B,然后按后退按钮,他们将返回到 /home 而不是项目 A。
这破坏了我的应用程序。
幸运的是,我做了一个测试,使用 useNavigate() 的行为符合预期(编辑:几乎。它目前在我的应用程序中似乎表现良好,但沙箱显示它不能 100% 工作)。
短期内,我通过 onClick 事件将 Link 组件替换为 useNavigate。但我宁愿使用 Link 组件。
我做错了什么吗?或者这是链接的错误?
代码(FWIW):
state: { project: model.id }
<Link to={pathname} state={state}>
{children}
</Link>
编辑:
按照建议,我创建了 3 个沙箱。
对于每个沙盒:
预计
实际发生了什么
CodeSandbox 1(React 16/路由器 5.2/使用链接) 沙盒1
CodeSandbox 2(React 18/路由器 6.22.3/使用链接)Sandbox 2
CodeSandbox 3(React 18/Router 6.22.3/使用 useNavigate() 而不是链接)Sandbox 3
这有点令人困惑,我不能肯定地说为什么是这种情况,但似乎您的 RRDv6 沙箱中的链接是“重定向”而不是正常的推送。将
replace={false}
添加到您的链接似乎会产生预期和期望的行为。
另请注意,在其他锚标记内嵌套锚标记是无效的。
import * as React from "react";
import { Route, Routes, Link, useLocation } from "react-router-dom";
import "./styles.css";
export default function App() {
return (
<div className="App">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/projects" element={<Project />} />
</Routes>
</div>
);
}
const Home = () => {
const linkData = { pathname: "/projects", state: { project: "A" } };
return (
<div>
<h1>Home</h1>
<Link to={linkData.pathname} state={linkData.state} replace={false}>
Project A
</Link>
</div>
);
};
const Project = () => {
const location = useLocation();
const project = location.state?.project;
const linkToA = { pathname: "/projects", state: { project: "A" } };
const linkToB = { pathname: "/projects", state: { project: "B" } };
const linkToUse = project === "A" ? linkToB : linkToA;
return (
<div>
<h1>Project</h1>
<h2>The project is {project}</h2>
<Link to={linkToUse.pathname} state={linkToUse.state} replace={false}>
Go to {project === "A" ? "B" : "A"}
</Link>
</div>
);
};