📋 目錄
你會拿到一份可回滾的兩階段升級流程,先安全上 v7,再決定要不要進一步做 route type safety 與 Framework adoption。
前言
React Router v7 常被講成「升級很簡單」,但團隊實作時最容易踩到的坑其實不是版本號,而是把不同層級的變更混在一起。像是 package 升級、import 遷移、typegen、route module 重構、Framework Mode 導入,這些工作量和風險都不同。
如果你把它們包裝成一條「低風險一次完成」路線,PR 會瞬間失控,回歸點也難追。這篇的核心就是把邊界切清楚:先做官方定義的 non-breaking upgrade,再把 typegen 與 Framework 能力當作第二階段專案。
文中範例都以 React Router 7.13.2(2026-04-01)為基準,並對應官方 Upgrading from v6 與 Route Module Type Safety 流程。
Phase 1:只做 non-breaking 升級(v6 -> v7)
先定義「non-breaking」在本文的範圍:
- 升到最新 v6 minor 並打開 future flags
- 升 v7 套件
- 把 import 由
react-router-dom收斂到react-router(含 DOM deep import) - 驗證既有行為不變
不包含 route module 大改、不包含 Vite plugin、不包含 SSR/SSG 轉換。
Step 0:先確認最低版本前提
node -v
npm ls react react-dom react-router-dom
React Router v7 官方最低要求是 node@20、react@18、react-dom@18。如果你還沒到這個基線,先處理基礎升級,不要直接跳 v7。
Step 1:先在 v6 打開 future flags
// Data Router 範例(createBrowserRouter)
const router = createBrowserRouter(routes, {
future: {
v7_relativeSplatPath: true,
v7_startTransition: true,
v7_fetcherPersist: true,
v7_normalizeFormMethod: true,
v7_partialHydration: true,
v7_skipActionErrorRevalidation: true,
},
});
這一步的目的不是「新功能」,而是先把 v7 行為差異搬到 v6 階段處理,讓每個變更都可獨立回滾。
Step 2:升級到 v7,再處理 package 收斂
# 先升級到 v7
npm install react-router-dom@latest
# 驗證穩定後,再收斂成 react-router 單一套件
npm uninstall react-router-dom
npm install react-router@latest
react-router-dom -> react-router 不建議跟前一步混在同一個大 PR。分開做,比較容易定位問題。
Step 3:精準遷移 import,而不是一次全域替換
// before
import { Link, Routes, Route, useNavigate } from "react-router-dom";
import { RouterProvider } from "react-router-dom";
// after
import { Link, Routes, Route, useNavigate } from "react-router";
// 注意:DOM 綁定 API 要走 deep import
import { RouterProvider } from "react-router/dom";
RouterProvider、HydratedRouter 這類依賴 react-dom 的 API 要走 react-router/dom。如果你在 Jest/非 DOM 情境測試,才用 top-level import。
Step 4:按 router 類型做風險驗證
npm run typecheck
npm test
npm run build
另外建議加兩類針對性檢查:
component routes:特別檢查dashboard/*這種 multi-segment splat 的相對連結data routers:檢查formMethod比對大小寫、fetcher 生命週期、action error 後 revalidation
Phase 2:Typegen 是「型別化專案」,不是 v6->v7 升級附贈
很多文章把 typegen 包成 v7 升級自帶收益,這個說法不精準。typegen 能成立,需要你先具備 route config 與對應 tooling 流程;這已經是第二階段工程。
Typegen 前提清單(至少要滿足這些)
- 專案路由結構可產生
+types(通常搭配 React Router dev tooling) tsconfig能吃.react-router/types- CI 有固定的 typegen 步驟
- 團隊接受 route module 型別約束(
Route.LoaderArgs等)
Step 1:設定 tsconfig 與 gitignore
{
"include": ["src", ".react-router/types/**/*"],
"compilerOptions": {
"rootDirs": [".", "./.react-router/types"],
"strict": true
}
}
.react-router/
Step 2:把 typegen 變成 CI gate
{
"scripts": {
"typegen": "react-router typegen",
"typecheck": "react-router typegen && tsc --noEmit"
}
}
如果你只靠本地 react-router dev 自動生型別,CI 很容易出現「本地過、雲端掛」的不一致。
Step 3:在 route module 吃 Route.* 型別
// src/routes/product.tsx
import type { Route } from "./+types/product";
export async function loader({ params }: Route.LoaderArgs) {
// params 會從路由定義推導出正確鍵名
const res = await fetch(`/api/products/${params.productId}`);
if (!res.ok) throw new Response("Not Found", { status: 404 });
return (await res.json()) as { name: string; price: number };
}
export default function ProductPage({ loaderData }: Route.ComponentProps) {
return (
<section>
<h1>{loaderData.name}</h1>
<p>NT$ {loaderData.price}</p>
</section>
);
}
這個階段的成果是 compile-time 保護,不是版本升級本身。請把 KPI 分開看,才不會錯估工期。
Framework adoption:第三層決策,獨立評估
官方文件把 Framework Adoption(不論從 Component Routes 或 RouterProvider 進入)定義成另一條遷移路徑,常見工作包含:
- 把路由定義移到 route modules
- 安裝
@react-router/devVite plugin - 新增
react-router.config.ts - 調整 entry/root 結構(例如
root.tsx、entry.client.tsx)
這些都不該被描述成「v6 -> v7 升級順手做」。更合理的做法是另開 epic,選 1~2 條路由先試點,再決定是否全面 rollout。
常見問題 / 注意事項
Q1:文章標題寫「低風險升級」,那 typegen 到底算不算低風險?
只在前提明確、拆成獨立 phase 時可以說「可控風險」。若把 typegen + framework adoption 和版本升級綁一起,就不算低風險。
Q2:可以直接把 react-router-dom 全域取代成 react-router 嗎?
不建議直接盲替換。至少要先盤點 DOM 專用 API,確認 react-router/dom deep import 是否正確。
Q3:Component Routes 與 Data Routers 的升級注意點一樣嗎?
不一樣。Data Routers 要額外檢查 future flags(fetcher、form method、revalidation),Component Routes 主要看路徑匹配與相對導覽。
Q4:什麼時候該考慮 Framework adoption?
當你已經完成 v7 穩定運行,且團隊確定要投資 route module、型別路由、SSR/預渲染策略時,再進入下一階段。
總結
React Router v7 的低風險升級,真正可承諾的只有 Phase 1:版本與 import 遷移加上行為驗證。typegen 與 Framework adoption 都是「可後續導入」的工程計畫,不是同一層成本。
實作上最穩的路線是:
- 先在 v6 打開 future flags 並修完警告
- 升 v7、完成 import 收斂、跑回歸
- 另開 Phase 2 導入 typegen(含 CI gate)
- 視需求再評估 Framework adoption
把邊界講清楚,你就能同時保住交付速度和升級品質。