React Router v7 的 framework mode 和 Remix 是什么关系?
Remix 一直是建在 React Router 之上的一层,v7 把这层并进了 React Router,原计划的 Remix v3 改为 React Router v7 发布。React Router 现在有 declarative、data、framework 三种模式,功能逐层叠加;framework mode 用 Vite 插件在 data mode 上加了类型安全的路由模块、代码拆分和 SPA、SSR、静态渲染,就是原来 Remix 的能力。Remix 品牌之后走向不依赖 React 的新方向。
简答
一个 Remix v2 项目升级,官方给的路线不是升到 Remix v3,而是改成 React Router v7:把
@remix-run/*依赖换成react-router,Vite 插件从remix()换成reactRouter()。因为 Remix 团队在 2024 年宣布,原计划的 Remix v3 改为 React Router v7 发布。原因是 Remix 一直只是 React Router 上面的一层,路由、loader、action 这些核心能力早就放进了 React Router,剩下的这层越来越薄,干脆合并。
合并以后,React Router 有三种模式,功能逐层叠加。declarative mode 就是熟悉的
<BrowserRouter>,只管 URL 匹配和导航;data mode 用createBrowserRouter把路由配置移到 React 渲染之外,加上 loader、action 和 pending 状态;framework mode 再用 Vite 插件包一层,提供类型安全的路由模块、按路由拆分代码,以及 SPA、SSR、静态渲染几种策略。framework mode 就是原来 Remix 提供的那套框架能力。要注意两点。第一,Remix 这个名字没有消失,团队 2025 年宣布 Remix 3 会走新路线,不再依赖 React,起点是 Preact 的一个分支,所以“Remix 3”和 React Router v7 是两回事。第二,React Router 已经发布 v8,framework mode 还在,但要求 Vite 7 并默认启用 Vite Environment API 等变更。
为什么 Remix 会并进 React Router
Remix 官方博客的说法是:Remix 一直只是 React Router 之上的一层。团队先把 Remix 的数据加载模式搬进 React Router(就是 v6.4 的 data router),后来又让 Remix 更多地直接依赖 React Router。到最后 Remix 自己的代码只剩很薄一层,所以决定去掉它,把原定的 Remix v3 作为 React Router v7 发布。
所以理解这件事的关键是:Remix 用户升级到 React Router v7,拿到的还是同一套框架能力,只是包名换了。官方说,在开启所有 future flag、并且已经用 Vite 的前提下,升级除了改 import 基本没有破坏性变更。
三种模式分别是什么
用哪种模式,取决于入口用的是哪个顶层路由 API。
declarative mode 写法和以前一样,只提供 URL 匹配、导航和激活状态,比如 <Link>、useNavigate、useLocation:
<BrowserRouter>
<App />
</BrowserRouter>
data mode 把路由配置移到 React 渲染之外,于是可以在渲染前加载数据:
const router = createBrowserRouter([
{ path: '/', Component: Root, loader: loadRootData },
]);
root.render(<RouterProvider router={router} />);
framework mode 在 data mode 外面包了一个 Vite 插件。路由写在 app/routes.ts 里,每个路由模块导出 loader、组件等,插件会生成对应的类型:
import type { Route } from './+types/product';
export async function loader({ params }: Route.LoaderArgs) {
const product = await getProduct(params.pid);
return { product };
}
export default function Product({ loaderData }: Route.ComponentProps) {
return <div>{loaderData.product.name}</div>;
}
loaderData 的类型直接从 loader 的返回值推出来,不用手写。<Links>、<Meta>、<Scripts>、<ServerRouter> 和 <Link prefetch> 这些 API 只有 framework mode 才有,因为它们需要构建工具知道每个路由对应哪些资源。
该选哪种模式
官方文档的建议很直接:每种模式都支持任何架构和部署目标,问题不是要不要 SSR,而是有多少事想自己做。
想直接用 React 做一个应用、拿不准要不要服务端渲染、或者在和 Next.js 之类的框架做比较、从 Next.js 迁移过来,选 framework mode。想要 loader、action 这些数据能力,但打包、数据层、服务端都想自己控制,或者 v6.4 起就在用 data router,选 data mode。只想把 React Router 当最简单的路由库用,或者数据层自己处理 pending 状态,选 declarative mode。
路由守卫和懒加载这类通用话题,见《React Router 的原理是什么?怎样做路由守卫和懒加载?》。
Remix v2 怎样升级
官方升级指南的主要步骤是:先开启 Remix v2 所有 future flag;运行社区提供的 codemod npx codemod remix/2/react-router/upgrade;把 @remix-run/react、@remix-run/server-runtime 等共享 API 改为从 react-router 导入,运行时相关的包改成 @react-router/node、@react-router/cloudflare 等;vite.config.ts 里的 remix() 换成 @react-router/dev/vite 的 reactRouter();路由改在 app/routes.ts 里声明,原来的配置挪到 react-router.config.ts;入口文件里的 RemixServer 和 RemixBrowser 换成 ServerRouter 和 HydratedRouter。
常见追问
Remix 3 是 React Router v7 的下一个版本吗?
不是。React Router v7 承接的是原来的 Remix v2 用户。Remix 团队 2025 年 5 月的博客说,新的 Remix 不会有关键依赖,连 React 都不依赖,起点是 Preact 的一个分支,并要构建自己的组件模型。
从 v7 升到 v8,framework mode 要改什么?
v8 要求 Node 22.22 以上、React 19.2.7 以上,framework mode 还要求 Vite 7。v7 的几个 future flag 变成默认行为,比如中间件、按路由拆分客户端模块、使用 Vite Environment API。另外
react-router-dom包被移除,DOM 相关的 API 从react-router/dom导入。官方建议在 v7 上把 flag 一个个打开、每步提交上线,再升 v8。
data mode 能做服务端渲染吗?
能。官方说每种模式都支持任何架构和部署目标,区别在于 framework mode 把 SSR、代码拆分和类型生成都配好了,data mode 要自己处理打包和服务端这部分。