在这篇文章写作时,React Router v6仍然处于alpha状态,但现在是时候开始玩它并探索即将到来的内容了。
正如你可能知道的,主要维护者在2018年初创建了React Router(LINK0)项目,以创建一个名为Reach Router(LINK1)的轻量级替代方案。
在此期间,这两个库都增长了,但似乎Reach Router的活跃开发将停止,并将合并到 即将到来的React Router v6
随着发布即将到来,这里是即将到来的东西的尖锐观点!
跳到...
is becoming - Big changes with
- Nested Routes are simpler
- useNavigate instead of useHistory
- From 20kb to 8kb
正在变成
这个顶级组件将被更名,但其功能大多保持不变。
1// v5
2import {
3 BrowserRouter,
4 Switch,
5 Route
6} from 'react-router-dom';
7
8function App() {
9 return (
10 <BrowserRouter>
11 <Switch>
12 <Route exact path="/"><Home /></Route>
13 <Route path="/profile"><Profile /></Route>
14 </Switch>
15 </BrowserRouter>
16 );
17}
只需点击路线
:
1// v6
2import {
3 BrowserRouter,
4 Routes,
5 Route
6} from 'react-router-dom';
7
8function App() {
9 return (
10 <BrowserRouter>
11 <Routes>
12 <Route path="/" element={<Home />} />
13 <Route path="profile/*" element={<Profile />} />
14 </Routes>
15 </BrowserRouter>
16 );
17}
巨大的变化与路线
在 v6 中,
将组件/返回器
替换为元素
:
1import Profile from './Profile';
2
3// v5
4<Route path=":userId" component={Profile} />
5<Route
6 path=":userId"
7 render={routeProps => (
8 <Profile routeProps={routeProps} animate={true} />
9 )}
10/>
11
12// v6
13<Route path=":userId" element={<Profile />} />
14<Route path=":userId" element={<Profile animate={true} />} />
如果你注意到,在v6中,现在通过补丁更容易,这已经否定了v5中的渲染
补丁的使用。
网游路线更简单
v5中的嵌套路径必须非常明确地定义,这需要将大量的符串匹配逻辑纳入这些组件中。
1// v5
2import {
3 BrowserRouter,
4 Switch,
5 Route,
6 Link,
7 useRouteMatch
8} from 'react-router-dom';
9
10function App() {
11 return (
12 <BrowserRouter>
13 <Switch>
14 <Route exact path="/" component={Home} />
15 <Route path="/profile" component={Profile} />
16 </Switch>
17 </BrowserRouter>
18 );
19}
20
21function Profile() {
22
23 let match = useRouteMatch();
24
25 return (
26 <div>
27 <nav>
28 <Link to={`${match.url}/me`}>My Profile</Link>
29 </nav>
30
31 <Switch>
32 <Route path={`${match.path}/me`}>
33 <MyProfile />
34 </Route>
35 <Route path={`${match.path}/:id`}>
36 <OthersProfile />
37 </Route>
38 </Switch>
39 </div>
40 );
41}
在 v6 中,你可以删除符串匹配逻辑. 也不需要使用 useRouteMatch()
! 结果很小:
1// v6
2import {
3 BrowserRouter,
4 Routes,
5 Route,
6 Link,
7 Outlet
8} from 'react-router-dom';
9
10// Approach #1
11function App() {
12 return (
13 <BrowserRouter>
14 <Routes>
15 <Route path="/" element={<Home />} />
16 <Route path="profile/*" element={<Profile/>} />
17 </Routes>
18 </BrowserRouter>
19 );
20}
21
22function Profile() {
23 return (
24 <div>
25 <nav>
26 <Link to="me">My Profile</Link>
27 </nav>
28
29 <Routes>
30 <Route path="me" element={<MyProfile />} />
31 <Route path=":id" element={<OthersProfile />} />
32 </Routes>
33 </div>
34 );
35}
36
37// Approach #2
38// You can also define all
39// <Route> in a single place
40function App() {
41 return (
42 <BrowserRouter>
43 <Routes>
44 <Route path="/" element={<Home />} />
45 <Route path="profile" element={<Profile />}>
46 <Route path=":id" element={<MyProfile />} />
47 <Route path="me" element={<OthersProfile />} />
48 </Route>
49 </Routes>
50 </BrowserRouter>
51 );
52}
53
54function Profile() {
55 return (
56 <div>
57 <nav>
58 <Link to="me">My Profile</Link>
59 </nav>
60
61 <Outlet />
62 </div>
63 )
64}
注意: {this.props.children}
。
使用代替使用历史
例如,在用户提交表单后,他们需要被重定向到确认页面,这是 v5 中的useHistory
库,在 v6 被更名为useNavigate
:
1// v5
2import { useHistory } from 'react-router-dom';
3
4function MyButton() {
5 let history = useHistory();
6 function handleClick() {
7 history.push('/home');
8 };
9 return <button onClick={handleClick}>Submit</button>;
10};
现在 history.push() 将取代 navigate():
1// v6
2import { useNavigate } from 'react-router-dom';
3
4function MyButton() {
5 let navigate = useNavigate();
6 function handleClick() {
7 navigate('/home');
8 };
9 return <button onClick={handleClick}>Submit</button>;
10};
在某些情况下,你会希望在浏览器历史中更换一个URL,而不是推一个新的URL。
1// v5
2history.push('/home');
3history.replace('/home');
4
5// v6
6navigate('/home');
7navigate('/home', {replace: true});
从 20KB 到 8KB
有了所有这些变化,你会期望包的大小会增加,但实际上它减少了一半! v5 的缩小包是 ~20kb,而 v6 只是 ~8kb。
使用 BundlePhobia工具计算包尺寸。
结论
我对React Router v6的发布感到非常兴奋,希望这篇文章给了你一个想法,当它发布时(这应该很快!)你可以阅读更多关于React Router v6的最新版本注释(https://github.com/ReactTraining/react-router/releases/tag/v6.0.0-alpha.2)
<$>[注] 新功能的完整列表,请参阅官方 React Router v6 迁移指南 <$>