跳到主要内容

版本差异

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
{
/** v7 不再支持此写法 */
}
<Route path="/user" component={User} />;
{
/** 必须使用 element */
}
<Route path="/about" element={<User />} />;

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

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

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

3. 新增 useNavigationTypeHook

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

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 和 loaderactionmeta
export const loader = async () => await fetch('/api/data');

6. 懒加载能力

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

7. 刷新策略

  • v6useNavigatenavigate(0)
  • v7router.revalidate() 主动刷新能力

8. 错误处理

  • v6 : 基础错误处理
  • v7 : 支持每个路由自定义 ErrorElement (出错不影响其他的 UI)
// 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)
// 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 中部分未稳定的功能被正式废弃或移除

三、 对比表格

特性v5v6v7
路由配置属性componentelement (推荐)强制 element
嵌套路由手动 children/render<Outlet /> 占位符同左,进一步优化类型
路由匹配<Switch> + exact<Routes> + 最长路径匹配同左,优化 SSR
导航 APIuseHistory()useNavigate()同左,新增 useNavigationType()
React 18 支持部分支持基础支持深度集成并发模式
SSR 体验一般改进进一步优化 hydration
  • v5 ➞ v6 : 重点强调路由配置 ( element 代替 component ) 、使用 <Outlet /> 处理嵌套、 替换 useHistory()useNavigate()
  • v6 ➞ v7 : 移除残留的 component 属性, 利用 React 18 并发特性优化加载体验,关注 SSR 场景的稳定性