react-router 变更日志深度解析:从 6.x 到 v8 的版本演进、破坏性变更与迁移要点

📅 发布时间:2026/9/8 22:03:05
react-router 变更日志深度解析:从 6.x 到 v8 的版本演进、破坏性变更与迁移要点 react-router 变更日志深度解析从 6.x 到 v8 的版本演进、破坏性变更与迁移要点【免费下载链接】react-routerDeclarative routing for React项目地址: https://gitcode.com/GitHub_Trending/re/react-routerpackages/react-router包的 CHANGELOG.md 是理解 React Router 演进路线的核心资料它完整记录了该核心包从 6.4.0 到当前 v8.3.0 的每一次 API 增删、破坏性变更、环境要求升级与安全修复。本文基于该变更日志逐项梳理 7.0.0 与 8.0.0 两大版本跃迁的实质内容、近期 v8.x 迭代中的关键能力演进并结合仓库源码印证若干变更的落地实现帮助你在升级依赖、排查行为差异或评估破坏性影响时快速定位权威依据。变更日志的定位与组织方式React Router 仓库采用 changesets 风格的版本管理核心包的变更历史集中记录在 packages/react-router/CHANGELOG.md 中与根目录的 CHANGELOG.md 相互独立。每个版本条目按语义化版本原则分为三类小节Major Changes破坏性变更升级前必须逐条阅读Minor Changes向后兼容的新特性通常伴随使用示例代码Patch Changes缺陷修复与内部改进部分版本额外包含Unstable Changes小节并明确标注“Unstable features are not recommended for production use”不稳定特性不建议用于生产环境。从文件内## v/## x.x.x标题可以看出该日志覆盖的完整版本跨度为v8.3.0最新→ v8.2.0 → v8.1.0 → v8.0.1 → v8.0.0 → v7.18.0 → … → v7.0.0 → 6.28.0 → … → 6.4.0文件末尾。与 package.json 中的version: 8.3.0一致可以确认当前仓库正处于 v8.3.0 发布节点。理解这份日志的价值在于React Router 在 v7/v8 期间完成了从“Remix 与 React Router 双品牌”到统一单包的架构收拢大量future.*开关被“转正”后移除。这些变更如果不阅读日志很难察觉其影响面尤其是环境要求Node/React 最低版本与包导入路径react-router-dom的移除这类会直接阻断构建的变更。7.0.0多包合并与环境基线上移v7.0.0 是该包历史上规模最大的一次重构Major Changes 小节可归纳为以下几个层面1. 包结构收拢remix-run 系列并入 react-router日志明确记录了四步合并remix-run/router并入react-routerreact-router-dom并入react-routerremix-run/server-runtime并入react-routerremix-run/testing并入react-router。合并带来大规模的导出清理。日志列出了被移除的公开导出例如原remix-run/router的AgnosticRouteObject、createRouter、createBrowserHistory改用createBrowserRouter、getStaticContextFromError等以及原react-router的Hash、Pathname、Search类型。其中createRemixStub更名为createRoutesStubRemixContext更名为FrameworkContextAction类型则以NavigationType之名从react-router导出Router数据路由器则以DataRouter导出以区别于 React 组件Router。同时为配合react-dom变为可选peerDependency新增了react-router/dom子路径导出DOM 环境下应从react-router/dom导入HydratedRouterVite 插件场景或RouterProvider手动创建createBrowserRouter/createHashRouter场景以避免在非 DOM 环境如createMemoryRouter的 Node 测试中盲目引入ReactDOM.flushSync。2. 旧版 defer 实现被 turbo-stream 取代v7 移除了原始defer实现改为通过 single fetch turbo-stream的裸 Promise 机制相应移除了defer、AbortedDeferredError、TypedDeferredData、UNSAFE_DeferredData、UNSAFE_DEFERRED_SYMBOL等导出。配套的future.v7_startTransition、future.v7_normalizeFormMethod、future.v7_prependBasename、future.v7_throwAbortReason、future.v7_relativeSplatPath、future.v7_partialHydration、future.v7_fetcherPersist等 future 标志全部移除。其中v7_partialHydration的移除带有明确迁移指引RouterProvider fallbackElement属性被删除应把 fallback 下沉为根路由的hydrateFallbackElement/HydrateFallback导出同时行为上有一处关联变更——开启该标志后初始加载期间state.navigation保持idle状态。3. Cookie/Session API 上收Web Crypto 成为硬性依赖createCookie、createCookieSessionStorage、createMemorySessionStorage、createSessionStorage改由react-router直接提供前提是运行环境具备 Web Crypto API 的crypto全局。原平台包的createCookieFactory、createSessionStorageFactory等低层工厂 API 被移除。日志同时给出旧 Node 环境的过渡方案remix-run/node的installGlobals会用 Node 的node:crypto的 webcrypto 实现填充globalThis.crypto注Node 20 已内置全局crypto此方案主要服务于遗留环境。4. 类型系统重构与类型生成v7.0.0 对 Remix 消费者的类型泛型做了迁移useFetcherLoaderData()应改为useFetchertypeof loader()并引入面向未来的Route.*类型体系。更重要的是该版本 Minor Changes 中的类型生成能力每个路由模块会自动生成类型可通过./types.文件名导入// app/routes/product.tsx import type * as Route from ./types.product; export function loader({ params }: Route.LoaderArgs) {} export default function Component({ loaderData }: Route.ComponentProps) {}初期覆盖Params来自 routes 配置含文件系统路由、LoaderData、ActionData并预告了类型安全的Link to/products/:id params{{ id: 1 }} /能力。当前仓库中对应的文档见 docs/how-to/route-module-type-safety.md 与 docs/explanation/type-safety.mdreact-router-dev包的 typegen 目录即其生成器实现。5. 其他 v7 亮点能力prerender 预渲染配置Vite 插件支持prerender字符串数组或同步/异步函数构建期生成.html与.data文件静态分发// react-router.config.ts import type { Config } from react-router/dev/config; export default { async prerender() { let slugs await fakeGetSlugsFromCms(); // Prerender these paths into .html files at build time, // and .data files if they have loaders return [/, /about, ...slugs.map((slug) /product/${slug})]; }, } satisfies Config;路由组件 props 注入Component、HydrateFallback、ErrorBoundary均可直接接收{ params, loaderData, actionData }unstable_dataStrategy稳定为dataStrategyunstable_patchRoutesOnNavigation稳定为patchRoutesOnNavigation二者是后续“懒路由发现/Lazy Route Discovery”的基础对应仓库 docs/explanation/lazy-route-discovery.md 与 docs/decisions/0002-lazy-route-modules.md 中的设计文档暴露底层 PromiseuseNavigate()、useSubmit、useFetcher().load/submit、useRevalidator.revalidate返回 Promise以便与 React 19 的use()组合移除future.v7_partialHydration、json工具改用Response.json、source-map依赖等。环境基线方面日志记录了两步推进先“Drop support for Node 16, SSR requires Node 18”随后“Drop support for Node 18, update minimum Node version to 20”React 最低版本升至 18。8.0.0future 标志全面落地与生态清理v8.0.0 的 Major Changes 是一次“只删不加”的大扫除其本质是把 v7 时期以future.*开关引入的新行为全部转正并提升生态下限1. 环境要求与产物形态发布产物切换为 ESM-onlypackages/下所有包CommonJS 用户需注意消费方式变化最低 Node 版本提升至 22.22.0最低 React 版本提升至 19.2.7tsconfig的target/lib从 ES2020 提升至 ES2022构建工具从tsup迁移到tsdown并发布产物保留独立模块文件的构建调整TypeScript 工具链升级至 TS 6。日志均明确标注“Published package entry points and public APIs are unchanged”说明这些是纯工程链路变更。2. 被移除的 future 标志与内部字段移除项转正后的行为future.v8_trailingSlashAwareDataRequests尾斜杠感知的数据请求 URL 成为默认行为future.v8_passThroughRequests原始request始终透传给loader/action需要“无 React Router 实现细节.data后缀、index/_routessearch params的规范化 URL”时使用url参数future.v8_middleware中间件恒为启用状态loader/action/middleware收到的context参数恒为RouterContextProvider实例自定义服务器的getLoadContext必须返回该实例不再支持返回普通对象MiddlewareEnabled类型与Future模块增强写法一并移除router.routes上的hasErrorBoundary内部字段路由器自行推断RouteObject/DataRouteObject/RouteJSX/lazy定义均不再接受该字段MapRoutePropertiesFunction签名也不再要求返回它此外metaAPI 的data参数被移除统一为loaderData涉及Route.MetaArgs、Route.MetaMatch、MetaArgs、MetaMatch、Route.ComponentProps.matches、UIMatch等类型使其与Route.ComponentProps对齐。3. react-router-dom 包被删除这是 v8 对 v6 遗留用户最直接的破坏v7 中 DOM 专属能力已收敛到react-router/domreact-router-dom仅为兼容 v6 导入保留。v8 中必须改写导入RouterProvider/HydratedRouter从react-router/dom导入其余 API 从react-router导入。v8.0.1 紧接着补充移除了 v7 遗留的废弃AppLoadContext类型导出——中间件恒启用后服务器请求上下文统一经RouterContextProvider提供。4. 依赖与类型修复Minor/Patch 层面cookie从^1.0.1升至^1.1.1set-cookie-parser从^2.6.0升至^3.1.0客户端中间件抛错时会先加载懒路由的错误边界再向上冒泡移除SharedFormProps上对onSubmit的显式类型覆盖修复types/react19.x下的弃用警告。v8.x 近期迭代安全、编码规范与 RSC 能力v8.1.0 v8.3.0 三个迭代均为 Minor/Patch但技术含金量高且可直接在源码中印证RFC 3986 路径参数编码v8.3.0href/generatePath对路径参数的编码从encodeURIComponent改为按 RFC 3986 path-segment 规则执行在 path segment 中可以字面出现的字符$ , ; : 即 RFC 3986pchar范畴不再被百分号编码——例如 semver 构建号1.0.01插值后保持原样而非变成1.0.0%2B1而结构性/不安全字符/ ? # %、空白、非 ASCII仍照旧转义。仓库中的实现见 packages/react-router/lib/router/utils.ts 的encodePathParam约 L1485-L1541注释中引用了 RFC 3986 §3.3 的pchar unreserved / pct-encoded / sub-delims / : / 定义并在 packages/react-router/lib/href.ts 中被href()复用splat 参数会先按/切段、逐段编码以保留路径分隔符。配套的 v8.2.0 条目“Fixhref()to properly stringify and URL-encode param values, matchinggeneratePath()”说明二者行为已对齐。createMemorySessionStorage 使用 crypto.randomUUID()v8.3.0日志强调createMemorySessionStorage仅面向本地开发与测试——服务器重启后会话全部丢失。源码 packages/react-router/lib/server-runtime/sessions/memoryStorage.ts 印证了这一变更createData回调中直接以crypto.randomUUID()生成会话 id 并存入Map。RSC 相关加固v8.3.0保留 RSC 路由组件元数据带clientLoader的路由在组件渲染后可跳过不必要的服务器请求同时仍能拉取缺失的服务端渲染元素加固 RSC CSRF 代码路径修复 RSC HTML 流存在待刷新数据时请求被中止导致的服务器崩溃TypeError: Invalid state: Unable to enqueue处理方式包括取消injectRSCPayload的 readable 侧、清空 pending flush 并取消底层 RSC payload 流。Unstable 小节标注不建议生产使用则包含两项前瞻能力陈旧 RSC 客户端检测懒路由发现过程中检测到客户端版本过期时自动 reload 目标文档。使用默认 RSC Framework 入口的应用无需改动自定义entry.rsc.tsx的应用需要引入生成的客户端版本并传给unstable_matchRSCServerRequestimport clientVersion from virtual:react-router/unstable_rsc/client-version; return unstable_matchRSCServerRequest({ // ... clientVersion, });RSC 文档渲染支持 CSP nonceunstable_routeRSCServerRequest与unstable_RSCStaticRouter新增nonce选项nonce 会传递到 HTML 渲染器并应用到注入的 RSC payload 脚本与 nonce 感知的框架组件。采用 nonce 型 CSP 的完整写法日志原样给出const nonce crypto.randomUUID(); const response await routeRSCServerRequest({ request, serverResponse, createFromReadableStream, nonce, async renderHTML(getPayload, options) { const payload getPayload(); return renderHTMLToReadableStream( RSCStaticRouter getPayload{getPayload} nonce{options.nonce} /, { ...options, bootstrapScriptContent, formState: await payload.formState, signal: request.signal, }, ); }, }); response.headers.set( Content-Security-Policy, script-src self nonce-${nonce}, );对应的 API 文档见 docs/api/rsc/routeRSCServerRequest.md 与 docs/api/rsc/RSCStaticRouter.md。关键特性的“转正”时间线从 unstable 到稳定变更日志清晰地展示了 React Router “unstable → future/vN → 默认行为 → 移除开关”的演进节奏几个值得重点关注的节点中间件middlewarev7.3.0 以future.unstable_middleware标志引入需在react-router.config.ts中开启标志并通过declare module react-router { interface Future { unstable_middleware: true } }增强类型路由模块通过unstable_middleware服务端与unstable_clientMiddleware客户端导出中间件数组中间件函数与loader/action参数一致并额外提供next——服务端中间件可拦截/改写next()返回的 HTTPResponse甚至throw redirect(...)短路整个管线日志给出了serverLogger、serverAuth等完整示例v7.15.0 将unstable_url等参数转正为urlv8.0.0 移除future.v8_middleware中间件恒启用。当前文档见 docs/how-to/middleware.md 与设计决策 docs/decisions/0014-context-middleware.md。instrumentation可观测性v7.15.0 将unstable_instrumentations稳定为instrumentationspattern同转正unstable_ServerInstrumentation等类型全部去掉unstable_前缀v8.1.0 进一步让服务器请求、客户端导航、fetcher 三类插桩在调用完成后返回路由元数据URL、匹配的路由 pattern、params服务器请求插桩结果还附带已知 HTTP 状态码。文档对应 docs/how-to/instrumentation.md 与 docs/decisions/0015-observability.md。unstable_useRouterStatev7.15.1Unstable以{ active, pending }结构统一useLocation、useSearchParams、useParams、useMatches、useNavigationType、useNavigation等钩子的访问方式active.location/params/matches/type与pending.state/formMethod/json/...日志提示这些旧钩子“可能在未来大版本中被弃用移除”。仓库测试 packages/react-router/tests/unstable-useRouterState-test.tsx 验证其行为。mask、defaultShouldRevalidate、useTransitions、normalizePath均在 v7.15.0 一次性稳定unstable_mask→mask并同步Location.mask字段unstable_defaultShouldRevalidate→defaultShouldRevalidate覆盖Link、Form、useLinkClickHandler、useSubmit、fetcher.submit、setSearchParamsunstable_useTransitions→useTransitions覆盖各类 Router 组件与useLinkClickHandlerunstable_normalizePath→normalizePath落地于staticHandler.query/queryRoute。日志对每一项都标注了“若已提前采用 unstable 版本则属破坏性变更”。类型安全工具改进v7.14.2 显著改善了generatePath的param参数类型——必填参数缺失会报Type null is not assignable to type string、可选参数允许省略、允许额外键v8.1.0 的插桩元数据与 v8.3.0 的编码规则则是该方向的自然延续。路由匹配性能优化脉络日志中多次出现路由匹配性能改进构成一条可追溯的优化线v7.15.0 “预计算展平/缓存路由分支”使服务端请求处理性能提升约 10-15%并改进了 Framework/Data 模式下的客户端匹配避免冗余matchRoutes调用恢复了 7.6.0 中回滚的优化整体基准测试报告 15-30% 的服务端请求处理提升v7.18.0 再次“Precompute route branch matchers to avoid recompiling route path regexes during matching”。从源码结构看这类优化与路由器内部对展平路由分支的缓存实现相一致可作为升级前后性能回归排查的对照点。v6 尾声与升级建议文件后半段6.21.0 6.28.0记录了 v6 的收尾如 v6.21.0 引入future.v7_*标志族、v6.19.0/v6.18.0 等的行为调整。对于仍停留在 v6 的读者变更日志给出的升级路径是先对照 v6.21 的future标志逐项开启并验证再按 v7.0.0 的 Major Changes 清单处理包导入react-router替代remix-run/react等、fallbackElement迁移与类型泛型调整最后关注 v8.0.0 的 ESM-only、react-router-dom移除、Node 22.22/React 19.2.7 下限。仓库中 docs/upgrading/v7.md、docs/upgrading/index.md 提供面向用户的升级指南与变更日志互为表里日志回答“改了什么”升级指南回答“该怎么改”。小结packages/react-router的 CHANGELOG.md 不仅是一份版本清单更是 React Router 架构演进的权威档案v7.0.0 完成了remix-run/*全家桶向单包的收拢、react-router/dom子路径导出、类型生成与dataStrategy/patchRoutesOnNavigation等核心能力定名v8.0.0 则以 ESM-only、react-router-dom删除、中间件/透传请求/尾斜杠感知默认化与更高的 Node/React 下限完成了生态清理v8.1.0 v8.3.0 在插桩元数据、RFC 3986 路径编码、crypto.randomUUID()会话 id 与 RSC nonce/陈旧客户端检测等方向持续深化。结合 packages/react-router/lib 下的实现源码如encodePathParam、memoryStorage.ts与 packages/react-router/tests中的对应测试可以逐条验证上述变更的落地细节这也是升级前做影响面评估时最可靠的证据来源。【免费下载链接】react-routerDeclarative routing for React项目地址: https://gitcode.com/GitHub_Trending/re/react-router创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考