跳到主要内容

版本差异

v6 是一次重大更新,目标是简化 API 、 提升性能,并更好的适配 [React] 新特性(如 <Suspense> )。而 v7 像是 v6 的优化版,重点是提升 [React] 18 的兼容性,并简化使用体验。

一、 [React Router] v5 到 v6 的主要区别

1.路由配置模式:从 componentelement

  • v5 使用 component 属性传递组件(需配合 renderchildren 处理参数)
    <Route path="/user" component={User} />
  • v6 强制使用 element 属性直接传递 JSX 元素(无需额外的处理参数,通过 useParams 等 hook 获取参数)
    <Route path="/user" element={<User />} />

2.嵌套路由: <Outlet> 替代隐式渲染

  • v5 处理嵌套路由需要手动通过 this.props.childrenrender 属性渲染子路由,结构复杂

    // 父组件
    <Route
    path="/parent"
    render={() => (
    <Parent>
    <Route path="child" component={Child} />
    </Parent>
    )}
    />
  • v6 则通过 <Outlet /> 占位符明确子路由渲染位置,结构更清晰

    // 父组件
    function Parent() {
    return (
    <div>
    <div>
    <h1>父级</h1>
    <Outlet />
    </div>
    </div>
    );
    }

    // 路由配置
    <Route path="/parent" element={<Parent />}>
    <Route path="child" element={<Child />} />
    </Route>;

3. 路由匹配: <Routes> 代替 <Switch>

  • v5 使用 <Switch> 按顺序匹配第一个符合的路由,需手动添加 exact 避免误匹配
    <Switch>
    <Route path="/" component={Home} exact />
    <Route path="/about" component={About} />
    </Switch>
  • v6 用 <Routes> 自动基于 **最长路径匹配 ( 无需 exact ),且支持相对路径(子路径相对于父路由)
    <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/about" element={<About />} />
    <Route path="parent" element={<Parent />}>
    <Route path="child" element={<Child />} />
    </Route>
    </Routes>

4. 导航 API : useHistory()useNavigate()

  • v5 通过 useHistory() 获取 history 对象,调用 push()/replace()/goBac()
    const history = useHistory();
    history.push('/new-path');
  • v6 使用 useNavigate() 提供更直观的导航方式
    const navigate = useNavigate();
    navigate('/new-path'); // 跳转
    navigate('/new-path', { replace: true }); // 替换当前记录
    navigate(-1); // 回退,等价于 goBack

5. <Suspense> 集成

v6 版本支持原生的 [React] 的 <Suspense> ,可包裹路由组件实现懒加载。

<Suspense fallback={<Loading/>}>
<Routes>
<Route path="/data" element={<DataComponent />}/>
</Route>

</Suspense>

需配合支持 <Suspense> 的数据加载方案,如 React Query 或 React Router 的 loader 函数。

6. 路由重定向

v5 使用 <Redirect> ,而在 v6 中推荐使用 <Navigate>

// v5
<Redirect to="/Home" />

// v6
<Navigate to="/home" />

7. 包大小

  • v5 : 约 20.8K(未压缩), 7.3K (压缩后)
  • v6 : 约 10.8K(未压缩), 3.8K (压缩后)

8. 路由配置方式:从 “分散”到“集中”

  • v5 : 通常在 JSX 中直接写 <Route> 分散配置
  • V6 : 推荐使用 createBrowserRouter() 等 API 集中处理路由配置(数组形式),再通过 RouterProvider 注入,更利于大型项目的维护
// v6 集中处理
const router = createBrowserRouter({
{path: '/', element: <Home />},
{
path: '/user',
element: <User />,
children: [
{
path: 'profile',
element: <Profile />
}
]
}
});

function App(){
return <RouterProvider router={router}>

}
```

### 9. 改进

- 移除了 `activeClassName` 和 `activeStyle`
- 移除 `withRouter` 高阶组件,推荐使用 `useLocation`/`useParams` 等 hook
- 引入了 `useRoutes` 代替 `react-router-config`
- 路径参数支持更灵活的正则匹配,如 `path="/user/:id(\\d+)"` 限制为数字

## 二、 [React Router] v6 ➞ v7 的主要区别

v7 采用新架构,使用 `Router Modules` + `Fetcher Pattern` ,低成对齐(借鉴) Remix

### 1.强制 `element` 属性,移除 `component`

- v6 中虽然推荐使用 `element` ,但仍保留 `component` 属性(可能引发警告)
- v7 中完全移除了 `component` ,仅支持 `element` ,强制统一 API

```jsx showLineNumbers
{
/** v7 不再支持此写法 */
}
<Route path="/user" component={User} />;
{
/** 必须使用 element */
}
<Route path="/about" element={<User />} />;
```` showLineNumbers

### 2. 深度集成了 [React] 18 并发特性

v7 优化了对 [React] 18 并发模式( `Concurrent Mode` )的支持,导航时更平滑:

- 支持 **中断渲染** :若用户在导航过程中触发新导航, [React] 18 可中断当前渲染,优先处理新请求
- 更好的 **数据加载协调** : 与 `useAsyncValue` 或 `useTransition` 配合,减少加载闪烁

### 3. 新增 `useNavigationTypeHook`

用于判断当前导航类型( `POP`/`PUSH`/`REPLACE` )帮助区分前进/回退/替换操作

```jsx showLineNumbers
import { useNavigateType } from 'react-route';

// 'POP' 表示前进
const navigateType = useNavigationType();
```

### 4. 优化服务器渲染 ( [SSR] )

v7 改进了 [SSR] 支持,减少 `hydration` 阶段的错误:

- 路由配置在服务端和客户端更一致,避免因异步加载导致的 `hydration` 不匹配
- 更高的 `StaticRouter` 支持,适配 `Next.js` 等框架的静态生成

### 5. 数据获取与加载

- **v6** : 基础 `loader`/`action` 支持
- **v7** : 引入 `Route Module` 架构,每个路由封装其 UI 和 `loader` 、 `action` 、 `meta` 等

```Jsx showLineNumbers
export const loader = async () => await fetch('/api/data');
```

### 6. 懒加载能力

- **v6** : 有限 `React.lazy`
- **v7** : 更强,路由本身可以按需懒加载 (模块级 `split` )

### 7. 刷新策略

- **v6** : `useNavigate` 、 `navigate(0)` 等
- **v7** : `router.revalidate()` 主动刷新能力

### 8. 错误处理

- **v6** : 基础错误处理
- **v7** : 支持每个路由自定义 `ErrorElement` (出错不影响其他的 UI)

```jsx showLineNumbers
// v7 路由示例
const route = {
path: '/user/:id',
element: <User />,
errorElement: <Errorpage />,
};

function Post() {
/** 获取路由相关错误 */
const error = useRouteError();
if (error) {
return <div>错误 : {error.message} </div>;
}
}
```

### 9. 数据缓存与重新验证

- **v6** : 基础 `loader()` 每次执行
- **v7** : 实验性支持缓存/重新验证机制(Revalidation)

```jsx showLineNumbers
// v7 数据加载 (进入路由前自动执行)
const router = createBrowserRouter([
{
path: '/posts/:id',
element: <Post />,
loader: async ({ params }) => {
// 加载数据
const res = await fetch(`/api/posts/${params.id}`);
return res.json();
},
action: async ({ request }) => {
// 处理提交(如表单)
const fromData = await request.formData();
return await updatePost(formData);
},
},
]);

// 组件中获取加载的数据
function Post() {
// v7 稳定钩子
const post = useLoaderData();
return <div>{post.title}</div>;
}
```

### 10. 新性能

- **`shouldRevalidate`** : 路由自定义是否重新请求 `loader` ,优化性能
- **`Fetcher` 模** : 提供统一的数据获取、提交、错误处理体验

### 11. 其他细节调整

- **`useParams` 性能优化** : 避免不必要的重新渲染( v6 中参数可能触发父组件重渲染, v7 优化了依赖追踪)
- **更严格的 TypeScript 类型** : 类型定义更精确,减少类型推断错误
- **移除试验性 API ** : 如 v6 中部分未稳定的功能被正式废弃或移除

## 三、 对比表格

| 特性 | v5 | v6 | v7 |
| :-----------------: | :----------------------- | :------------------------ | :------------------------------- |
| **路由配置属性** | `component` | `element` (推荐) | 强制 `element` |
| **嵌套路由** | 手动 `children`/`render` | `<Outlet />` 占位符 | 同左,进一步优化类型 |
| **路由匹配** | `<Switch>` + `exact` | `<Routes>` + 最长路径匹配 | 同左,优化 [SSR] |
| **导航 API** | `useHistory()` | `useNavigate()` | 同左,新增 `useNavigationType()` |
| **[React] 18 支持** | 部分支持 | 基础支持 | 深度集成并发模式 |
| **[SSR] 体验** | 一般 | 改进 | 进一步优化 `hydration` |

- **v5 ➞ v6** : 重点强调路由配置 ( `element` 代替 `component` ) 、使用 `<Outlet />` 处理嵌套、 替换 `useHistory()` 为 `useNavigate()`
- **v6 ➞ v7** : 移除残留的 `component` 属性, 利用 [React] 18 并发特性优化加载体验,关注 [SSR] 场景的稳定性

[React]: https://zh-hans.react.dev/
[React Router]: https://reactrouter.com/
[SPA]: /glossary/s#spa
[SSR]: /glossary/s#ssr