前言
没事翻了翻 的文档,发现已推到了 版本,这个版本做了很大的改动,让我们一起看看吧React Router
v6.2.2
为什么推出 v6
- 推出 的最大原因是 的出现
v6
React Hooks
v6
写的代码要比 代码更加紧凑和优雅v5
我们通过代码来感受下,这是 写的伪代码v6
import { Routes, Route, useParams } from "react-router-dom"; function App() { return ( <Routes> <Route path="blog/:id" element={<Head />} /> </Routes> ); } function Head() { let { id } = useParams(); return ( <> <Footer /> </> ); } function Footer() { let { id } = useParams(); }
这是 写的伪代码v5
import * as React from "react"; import { Switch, Route } from "react-router-dom"; class App extends React.Component { render() { return ( <Switch> <Route path="head/:id" render={({ match }) => ( <Head id={match.params.id} /> )} /> </Switch> ); } } class Head extends React.Component { render() { return ( <> <Footer id={this.props.id} /> </> ); } } class Footer extends React.Component { render() { return ( <> <ButtonComponent id={this.props.id} /> </> ); } }
这个例子表明
Hooks
消除了使用 访问路由器内部状态的需要<Route render>
- 手动传递 将该状态传播到子组件的需要
props
- 应用程序包体积更小
增加了哪些特性?
<Switch>
升级为<Routes>
- Routes 内的所有 和 是相对的。这使得 和 中的代码更精简、更可预测
- 路由是根据最佳匹配,而不是按顺序遍历,这避免了由于路由不可达而导致的错误
- 路由可以嵌套在一个地方,而不是分散在不同的组件中
- 新钩子 代替
useRoutes
react-router-config
之前:
import React, { lazy } from 'react'; import PrivateRoute from '@components/PrivateRoute/index'; const Dashboard = lazy(() => import('@pages/dashboard/index')); const Abount = lazy(() => import('@pages/abount/index')); const routes = [ { path: '/home', component: Dashboard }, { path: '/about', component: Abount }, ]; const RouteWithSubRoutes = route => ( <PrivateRoute path={route.path} component={route.component} routes={route.routes} /> ); const routeConfig = routes.map((route, i) => <RouteWithSubRoutes key={i} {...route} />); export default routeConfig;
现在
function App() { let element = useRoutes([ { path: '/', element: <Home /> }, { path: 'users', element: <Users />, children: [ { path: '/', element: <UsersIndex /> }, { path: ':id', element: <UserProfile /> }, { path: 'me', element: <OwnUserProfile /> }, ] } ]); return element; }
就感觉更优雅一些
- 用 代替
useNavigate
useHistory
之前
import { useHistory } from "react-router-dom"; function App() { let history = useHistory(); function handleClick() { history.push("/home"); } return ( <div> <button onClick={handleClick}>go home</button> </div> ); }
现在
import { useNavigate } from "react-router-dom"; function App() { let navigate = useNavigate(); function handleClick() { navigate("/home"); } return ( <div> <button onClick={handleClick}>go home</button> </div> ); }
这个变化不是很大
- Route 的变化
- 4.1 移除,使用 代替
<Route exact>
/*
<Route path="/*" element={<Home />} />
`
- 4.2 使用 代替
<Route children>
<Route element>
import Profile from './Profile'; // v5 <Route path=":userId" component={<Profile />} /> // v6 <Route path=":userId" element={<Profile />} />
- 4.3 Outlet
我们使用一个 元素作为占位符。在 这种情况下, 组件如何呈现其子路由。因此,将根据当前位置 呈现一个 或 元素<Outlet>
<Outlet>
Users
<Outlet>
<UserProfile>
<OwnUserProfile>
- 4.4
import { BrowserRouter, Routes, Route, Link, Outlet } from 'react-router-dom'; function App() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> <Route path="users" element={<Users />}> <Route path="/" element={<UsersIndex />} /> <Route path=":id" element={<UserProfile />} /> <Route path="me" element={<OwnUserProfile />} /> </Route> </Routes> </BrowserRouter> ); } function Users() { return ( <div> <nav> <Link to="me">My Profile</Link> </nav> <Outlet /> </div> ); }
体验 v6
这里我们使用 来创建项目,安装好之后,进入项目,安装 依赖create-react-app
react-router-dom@6
$ npx create-react-app react-app $ cd react-app $ npm install react-router-dom@6
src/index.js
在编辑器中打开, 从顶部附近导入 并将 包装在 BrowserRouter
react-router-dom
<APP>
<BrowserRouter>
// src/index.js import * as React from "react"; import * as ReactDOM from "react-dom"; import { BrowserRouter } from "react-router-dom"; import "./index.css"; import App from "./App"; import * as serviceWorker from "./serviceWorker"; ReactDOM.render( <BrowserRouter> <App /> </BrowserRouter>, document.getElementById("root") );
打开 并用一些路由替换默认标记src/App.js
// App.js import * as React from "react"; import { Routes, Route, Link } from "react-router-dom"; import "./App.css"; function App() { return ( <div className="App"> <h1>Welcome to React Router!</h1> <Routes> <Route path="/" element={<Home />} /> <Route path="about" element={<About />} /> </Routes> </div> ); }
现在,仍在 ,创建你的路由组件src/App.js
// src/App.js function Home() { return ( <> <main> <h2>Home</h2> </main> <nav> <Link to="/about">About</Link> </nav> </> ); } function About() { return ( <> <main> <h2>About</h2> </main> <nav> <Link to="/">Home</Link> </nav> </> ); }
运行 ,您应该会看到 标识npm start
Home
如何升级 v6
官方的迁移指南在这里:React Router v6 迁移指南
参考文章
结语
如果你正在用 重构你的应用,我的建议是可以尝试Hook