React Router v6 升级到 v7 完全指南
前言
React Router 作为 React 生态中最流行的路由解决方案,其 v7 版本带来了一些重要的改进和优化。本文将详细介绍如何从 v6 版本平滑升级到 v7 版本,帮助开发者理解升级过程中的关键点和注意事项。
升级前的准备工作
环境要求
在开始升级前,请确保你的开发环境满足以下最低版本要求:
- Node.js 20 或更高版本
- React 18 或更高版本
- React DOM 18 或更高版本
升级策略
React Router 团队采用了渐进式升级策略,通过引入未来标志(future flags)让你可以逐步适应 v7 的变化。建议按照以下步骤进行升级:
- 首先升级到最新的 v6.x 版本
- 逐个启用未来标志
- 每次变更后提交代码并测试
- 最后升级到 v7 版本
逐步升级步骤
第一步:升级到最新 v6.x 版本
npm install react-router-dom@6
关键未来标志详解
1. v7_relativeSplatPath
背景:这个标志改变了多段路径(如 dashboard/*
)的相对路径匹配和链接行为。
启用方式:
<BrowserRouter
future={{
v7_relativeSplatPath: true,
}}
/>
或
createBrowserRouter(routes, {
future: {
v7_relativeSplatPath: true,
},
});
代码调整:
需要将多段路径的 <Route>
拆分为父路径和子路径:
<Routes>
<Route path="/" element={<Home />} />
- <Route path="dashboard/*" element={<Dashboard />} />
+ <Route path="dashboard">
+ <Route path="*" element={<Dashboard />} />
+ </Route>
</Routes>
同时更新相关链接:
function Dashboard() {
return (
<div>
<h2>Dashboard</h2>
<nav>
- <Link to="/">Dashboard Home</Link>
- <Link to="team">Team</Link>
- <Link to="projects">Projects</Link>
+ <Link to="../">Dashboard Home</Link>
+ <Link to="../team">Team</Link>
+ <Link to="../projects">Projects</Link>
</nav>
</div>
);
}
2. v7_startTransition
背景:使用 React 的 useTransition
替代 useState
来处理路由状态更新。
启用方式:
<BrowserRouter
future={{
v7_startTransition: true,
}}
/>
注意事项:如果你在组件内部使用 React.lazy
,需要将其移到模块作用域,因为 useTransition
与组件内部创建 Promise 不兼容。
3. v7_fetcherPersist
背景:fetcher 的生命周期现在基于它何时返回空闲状态,而不是其所有者组件何时卸载。
启用方式:
createBrowserRouter(routes, {
future: {
v7_fetcherPersist: true,
},
});
影响评估:检查 useFetchers
的使用情况,因为 fetcher 可能会比之前持续更长时间。
4. v7_normalizeFormMethod
背景:将 formMethod
字段规范化为大写的 HTTP 方法,与 fetch()
行为保持一致。
启用方式:
createBrowserRouter(routes, {
future: {
v7_normalizeFormMethod: true,
},
});
代码调整:
-useNavigation().formMethod === "post"
-useFetcher().formMethod === "get";
+useNavigation().formMethod === "POST"
+useFetcher().formMethod === "GET";
5. v7_partialHydration
背景:支持数据路由的部分水合,主要用于 SSR 框架。
启用方式:
createBrowserRouter(routes, {
future: {
v7_partialHydration: true,
},
});
代码调整:
const router = createBrowserRouter(
[
{
path: "/",
Component: Layout,
+ HydrateFallback: Fallback,
children: [],
},
],
);
6. v7_skipActionErrorRevalidation
背景:当 action 抛出错误或返回 4xx/5xx 状态码时,默认不再重新验证 loader。
启用方式:
createBrowserRouter(routes, {
future: {
v7_skipActionErrorRevalidation: true,
},
});
处理方案:
- 修改 action 避免在错误情况下进行数据变更
- 通过
shouldRevalidate
和actionStatus
参数选择性地重新验证
废弃功能
json
和 defer
方法已被废弃,建议直接返回原始对象:
async function loader() {
- return json({ data });
+ return { data };
如果需要 JSON 序列化,可以使用原生 Response.json()
方法。
升级到 v7
完成上述准备工作后,可以安全升级到 v7 版本:
npm install react-router@latest
重要变化
- 包结构调整:不再需要
react-router-dom
,所有功能都整合到react-router
中
npm uninstall react-router-dom
npm install react-router@latest
- 导入更新:
-import { useLocation } from "react-router-dom";
+import { useLocation } from "react-router";
- DOM 相关导入:
-import { RouterProvider } from "react-router-dom";
+import { RouterProvider } from "react-router/dom";
对于非 DOM 环境(如测试):
-import { RouterProvider } from "react-router-dom";
+import { RouterProvider } from "react-router";
升级后的验证
完成升级后,建议:
- 全面测试应用的所有路由功能
- 检查控制台是否有警告信息
- 验证数据加载和表单提交行为
- 测试嵌套路由和相对链接
总结
React Router v7 的升级过程设计得非常平滑,通过未来标志可以逐步适应变化。本文详细介绍了每个关键变化的背景、启用方式和代码调整建议,帮助开发者顺利完成升级。记住遵循"小步前进、频繁测试"的原则,可以最大程度减少升级带来的风险。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考