前言
沒事翻了翻 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 內的所有 <Route> 和 <Link> 是相對的。這使得 <Route path> 和 <Link to> 中的程式碼更精簡、更可預測
- 路由是根據最佳匹配,而不是按順序遍歷,這避免了由於路由不可達而導致的錯誤
- 路由可以巢狀在一個地方,而不是分散在不同的元件中
- 新鉤子
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
重構你的應用,我的建議是可以嘗試
重要的事
如果你覺得這篇內容對你挺有啟發,別忘記點贊 + 關注
歡迎新增我的個人微信:Jiang9684,一起交流前端技術
我的部落格地址