react-router-dom v5到v6改变了哪些属性

前言

18 年初,React Router的主要开发人员创建一个名为Reach Router的轻量级替代方案。

原来是相互抗衡的,却没想React Router直接拿来合并(真香!)

目前 v6已是测试最后一版,估计新的特性不出意外就是下面这些了:

  1. <Switch>重命名为<Routes>

  2. <Route>的新特性变更。

  3. 嵌套路由变得更简单。

  4. useNavigate代替useHistory

  5. 新钩子useRoutes代替react-router-config

  6. 大小减少:从20kb8kb

1. <Switch>重命名为<Routes>

该顶级组件将被重命名。但是,其功能大部分保持不变(嗨,瞎折腾)。

 
  1. // v5

  2. <Switch>

  3. <Route exact path="/"><Home /></Route>

  4. <Route path="/profile"><Profile /></Route>

  5. </Switch>

  6. // v6

  7. <Routes>

  8. <Route path="/" element={<Home />} />

  9. <Route path="profile/*" element={<Profile />} />

  10. </Routes>

2. <Route>的新特性变更

component/renderelement替代

总而言之,简而言之。就是变得更好用了。

 
  1. import Profile from './Profile';

  2. // v5

  3. <Route path=":userId" component={Profile} />

  4. <Route

  5. path=":userId"

  6. render={routeProps => (

  7. <Profile routeProps={routeProps} animate={true} />

  8. )}

  9. />

  10. // v6

  11. <Route path=":userId" element={<Profile />} />

  12. <Route path=":userId" element={<Profile animate={true} />} />

3. 嵌套路由变得更简单

具体变化有以下:

  • <Route children> 已更改为接受子路由。

  • <Route exact><Route strict>更简单的匹配规则。

  • <Route path> 路径层次更清晰。

3.1 简化嵌套路由定义

v5中的嵌套路由必须非常明确定义,且要求在这些组件中包含许多字符串匹配逻辑(活久见啊,终于意识到这个问题了。)

且看之前的处理:

 
  1. // v5

  2. import {

  3. BrowserRouter,

  4. Switch,

  5. Route,

  6. Link,

  7. useRouteMatch

  8. } from 'react-router-dom';

  9. function App() {

  10. return (

  11. <BrowserRouter>

  12. <Switch>

  13. <Route exact path="/" component={Home} />

  14. <Route path="/profile" component={Profile} />

  15. </Switch>

  16. </BrowserRouter>

  17. );

  18. }

  19. function Profile() {

  20. let { path, url } = useRouteMatch();

  21. return (

  22. <div>

  23. <nav>

  24. <Link to={`${url}/me`}>My Profile</Link>

  25. </nav>

  26. <Switch>

  27. <Route path={`${path}/me`}>

  28. <MyProfile />

  29. </Route>

  30. <Route path={`${path}/:id`}>

  31. <OthersProfile />

  32. </Route>

  33. </Switch>

  34. </div>

  35. );

  36. }

而在v6中,你可以删除字符串匹配逻辑。不需要任何useRouteMatch()

 
  1. // v6

  2. import {

  3. BrowserRouter,

  4. Routes,

  5. Route,

  6. Link,

  7. Outlet

  8. } from 'react-router-dom';

  9. function App() {

  10. return (

  11. <BrowserRouter>

  12. <Routes>

  13. <Route path="/" element={<Home />} />

  14. <Route path="profile/*" element={<Profile/>} />

  15. </Routes>

  16. </BrowserRouter>

  17. );

  18. }

  19. function Profile() {

  20. return (

  21. <div>

  22. <nav>

  23. <Link to="me">My Profile</Link>

  24. </nav>

  25. <Routes>

  26. <Route path="me" element={<MyProfile />} />

  27. <Route path=":id" element={<OthersProfile />} />

  28. </Routes>

  29. </div>

  30. );

  31. }

当然,还有更酸爽的操作,直接在路由里定义<Route><Route>,然后用接下来的一个新APIOutlet

3.2 新API:Outlet

这玩意儿,像极了{this.props.children},具体用法看以下例子:

 
  1. function App() {

  2. return (

  3. <BrowserRouter>

  4. <Routes>

  5. <Route path="/" element={<Home />} />

  6. <Route path="profile" element={<Profile />}>

  7. <Route path=":id" element={<MyProfile />} />

  8. <Route path="me" element={<OthersProfile />} />

  9. </Route>

  10. </Routes>

  11. </BrowserRouter>

  12. );

  13. }

  14. function Profile() {

  15. return (

  16. <div>

  17. <nav>

  18. <Link to="me">My Profile</Link>

  19. </nav>

  20. {/*

  21. 将直接根据上面定义的不同路由参数,渲染<MyProfile />或<OthersProfile />

  22. */}

  23. <Outlet />

  24. </div>

  25. )

  26. }

3.3 多个<Routes />

以前,我们只能 在React App中使用一个 Routes。但是现在我们可以在React App中使用多个路由,这将帮助我们基于不同的路由管理多个应用程序逻辑。

 
  1. import React from 'react';

  2. import { Routes, Route } from 'react-router-dom';

  3. function Dashboard() {

  4. return (

  5. <div>

  6. <p>Look, more routes!</p>

  7. <Routes>

  8. <Route path="/" element={<DashboardGraphs />} />

  9. <Route path="invoices" element={<InvoiceList />} />

  10. </Routes>

  11. </div>

  12. );

  13. }

  14. function App() {

  15. return (

  16. <Routes>

  17. <Route path="/" element={<Home />} />

  18. <Route path="dashboard/*" element={<Dashboard />} />

  19. </Routes>

  20. );

  21. }

4. 用useNavigate代替useHistory

从一目了然改到双目失明。。。

总感觉React Router团队有点儿戏。。。

 
  1. // v5

  2. import { useHistory } from 'react-router-dom';

  3. function MyButton() {

  4. let history = useHistory();

  5. function handleClick() {

  6. history.push('/home');

  7. };

  8. return <button onClick={handleClick}>Submit</button>;

  9. };

现在,history.push()将替换为navigation()

 
  1. // v6

  2. import { useNavigate } from 'react-router-dom';

  3. function MyButton() {

  4. let navigate = useNavigate();

  5. function handleClick() {

  6. navigate('/home');

  7. };

  8. return <button onClick={handleClick}>Submit</button>;

  9. };

history的用法也将被替换成:

 
  1. // v5

  2. history.push('/home');

  3. history.replace('/home');

  4. // v6

  5. navigate('/home');

  6. navigate('/home', {replace: true});

强行达成共识

5. 新钩子useRoutes代替react-router-config

感觉又是一波强行hooks,但还是相对于之前简洁了一些。。。

 
  1. function App() {

  2. let element = useRoutes([

  3. { path: '/', element: <Home /> },

  4. { path: 'dashboard', element: <Dashboard /> },

  5. { path: 'invoices',

  6. element: <Invoices />,

  7. children: [

  8. { path: ':id', element: <Invoice /> },

  9. { path: 'sent', element: <SentInvoices /> }

  10. ]

  11. },

  12. // 重定向

  13. { path: 'home', redirectTo: '/' },

  14. // 404找不到

  15. { path: '*', element: <NotFound /> }

  16. ]);

  17. return element;

  18. }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值