React-Router v6 新特性解读及迁移指南
前言
18 年初, React Router
的主要开发人员创建一个名为 Reach Router
的轻量级替代方案。
原来是相互抗衡的,却没想 React Router
直接拿来合并(真香!)
目前 v6
已是测试最后一版,估计新的特性不出意外就是下面这些了:
-
重命名为
。 -
的新特性变更。 - 嵌套路由变得更简单。
-
用
useNavigate
代替useHistory
。 -
新钩子
useRoutes
代替react-router-config
。 -
大小减少:从
20kb
到8kb
1.
重命名为
该顶级组件将被重命名。但是,其功能大部分保持不变(嗨,瞎折腾)。
// v5
// v6 <Route path="/" element={} /> <Route path="profile/*" element={} />
2.
的新特性变更
component/render
被 element
替代
总而言之,简而言之。就是变得更好用了。
import Profile from './Profile';
// v5 <Route path=":userId" render={routeProps => ( )} />
// v6 <Route path=":userId" element={} /> <Route path=":userId" element={} />
3. 嵌套路由变得更简单
具体变化有以下:
-
已更改为接受子路由。 -
比
和
更简单的匹配规则。 -
路径层次更清晰。
3.1 简化嵌套路由定义
v5
中的嵌套路由必须非常明确定义,且要求在这些组件中包含许多字符串匹配逻辑(活久见啊,终于意识到这个问题了。)

且看之前的处理:
// v5 import { BrowserRouter, Switch, Route, Link, useRouteMatch } from 'react-router-dom';
function App() { return ( ); }
function Profile() { let { path, url } = useRouteMatch();
return (My Profile); }
而在 v6
中,你可以删除字符串匹配逻辑。不需要任何 useRouteMatch()
!
// v6 import { BrowserRouter, Routes, Route, Link, Outlet } from 'react-router-dom';
function App() { return ( <Route path="/" element={} /> <Route path="profile/*" element={} /> ); }
function Profile() { return (My Profile); }
<Route path="me" element={} /> <Route path=":id" element={} />
当然,还有更酸爽的操作,直接在路由里定义
的
,然后用接下来的一个新 API
: Outlet
3.2 新 API
: Outlet
这玩意儿,像极了 {this.props.children}
,具体用法看以下例子:
function App() { return ( <Route path="/" element={} /> <Route path="profile" element={}> <Route path=":id" element={} /> <Route path="me" element={} /> ); }
function Profile() { return (My Profile {/* 将直接根据上面定义的不同路由参数,渲染或 */}) }
3.3 多个
以前,我们只能 在 React App
中使用一个 Routes
。但是现在我们可以在 React App
中使用多个路由,这将帮助我们基于不同的路由管理多个应用程序逻辑。
import React from 'react'; import { Routes, Route } from 'react-router-dom';
function Dashboard() { return (); }Look, more routes!
<Route path="/" element={} /> <Route path="invoices" element={} />
function App() { return ( <Route path="/" element={} /> <Route path="dashboard/*" element={} /> ); }
4. 用 useNavigate
代替 useHistory
从一目了然改到双目失明。。。
总感觉 React Router
团队有点儿戏。。。
// v5 import { useHistory } from 'react-router-dom';
function MyButton() { let history = useHistory(); function handleClick() { history.push('/home'); }; return ; };
现在, history.push()
将替换为 navigation()
:
// v6 import { useNavigate } from 'react-router-dom';
function MyButton() { let navigate = useNavigate(); function handleClick() { navigate('/home'); }; return ; };
history
的用法也将被替换成:
// v5 history.push('/home'); history.replace('/home');
// v6 navigate('/home'); navigate('/home', {replace: true});

5. 新钩子 useRoutes
代替 react-router-config
。
感觉又是一波强行 hooks
,但还是相对于之前简洁了一些。。。
function App() { let element = useRoutes([ { path: '/', element: }, { path: 'dashboard', element: }, { path: 'invoices', element: , children: [ { path: ':id', element: }, { path: 'sent', element: } ] }, // 重定向 { path: 'home', redirectTo: '/' }, // 404找不到 { path: '*', element: } ]); return element; }
6. 大小减少:从 20kb
到 8kb
React Router v6
给我们带来方便的同时,还把包减少了一半以上的体积。。。

感觉可以去看一波源码了。。。
关于奇舞周刊
《奇舞周刊》是360公司大前端团队「 奇舞团
」运营的前端技术社区。关注公众号后,直接发送链接到后台即可给我们投稿。