第九章 React Router 6
一、概述
-
React Router 以三个不同的包发布到 npm 上,它们分别为:
- react-router: 路由的核心库,提供了很多的:组件、钩子。
- react-router-dom: 包含 react-router 所有内容,并添加一些专门用于 DOM 的组件,例如
<BrowserRouter>
等 。 - react-router-native: 包括 react-router 所有内容,并添加一些专门用于 ReactNative 的 API,例如:
<NativeRouter>
等。
-
与 React Router 5.x 版本相比,改变了什么?
-
内置组件的变化:移除
<Switch/>
,新增<Routes/>
等。 -
语法的变化:
component={About}
变为element={<About/>}
等。 -
新增多个 hook:
useParams
、useNavigate
、useMatch
等。 -
官方明确推荐函数式组件了!!!
…
-
-
安装:npm install react-router-dom
二、代码实战
1. 一级路由
1.1 index.html
<!-- public/index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>路由测试</title>
<link rel="stylesheet" href="/css/bootstrap.css" />
<style>
.alex {
background-color: orange !important;
color: white !important;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
</html>
1.2 index.js
/* src/index.js */
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import App from "./App";
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root")
);
1.3 App.jsx
/* src/App.jsx */
import React from "react";
import { NavLink, Routes, Route } from "react-router-dom";
import About from "./pages/About";
import Home from "./pages/Home";
export default function App() {
return (
<div>
<div className="row">
<div className="col-xs-offset-2 col-xs-8">
<div className="page-header">
<h2>React Router Demo</h2>
</div>
</div>
</div>
<div className="row">
<div className="col-xs-2 col-xs-offset-2">
<div className="list-group">
{/* 路由链接 */}
<NavLink className="list-group-item" to="/about">
About
</NavLink>
<NavLink className="list-group-item" to="/home">
Home
</NavLink>
</div>
</div>
<div className="col-xs-6">
<div className="panel">
<div className="panel-body">
{/* 注册路由 */}
<Routes>
<Route path="/about" element={<About />} />
<Route path="/home" element={<Home />} />
</Routes>
</div>
</div>
</div>
</div>
</div>
);
}
1.4 About.jsx
/* src/pages/About.jsx */
import React from 'react'
export default function About() {
return (
<h3>我是About的内容</h3>
)
}
1.5 Home.jsx
/* src/pages/Home.jsx */
import React from 'react'
export default function Home() {
return (
<h3>我是Home的内容</h3>
)
}
2. 重定向
2.1 App.jsx
/* src/App.jsx */
import React from "react";
import { NavLink, Routes, Route, Navigate } from "react-router-dom";
import About from "./pages/About";
import Home from "./pages/Home";
export default function App() {
return (
<div>
<div className="row">
<div className="col-xs-offset-2 col-xs-8">
<div className="page-header">
<h2>React Router Demo</h2>
</div>
</div>
</div>
<div className="row">
<div className="col-xs-2 col-xs-offset-2">
<div className="list-group">
{/* 路由链接 */}
<NavLink className="list-group-item" to="/about">
About
</NavLink>
<NavLink className="list-group-item" to="/home">
Home
</NavLink>
</div>
</div>
<div className="col-xs-6">
<div className="panel">
<div className="panel-body">
{/* 注册路由 */}
<Routes>
<Route path="/ABOUT" element={<About />} />
<Route path="/home" element={<Home />} />
<Route path="/" element={<Navigate to="/about" />} />
</Routes>
</div>
</div>
</div>
</div>
</div>
);
}
2.2 Home.jsx
/* src/pages/Home.jsx */
import React, { useState } from "react";
import { Navigate } from "react-router-dom";
export default function Home() {
const [sum, setSum] = useState(1);
return (
<div>
<h3>我是Home的内容</h3>
{sum === 2 ? (
<Navigate to="/about" replace={true} />
) : (
<h4>当前sum的值是:{sum}</h4>
)}
<button onClick={() => setSum(2)}>点我将sum变为2</button>
</div>
);
}
3. NavLink 高亮
App.jsx
/* src/App.jsx */
import React from "react";
import { NavLink, Routes, Route, Navigate } from "react-router-dom";
import About from "./pages/About";
import Home from "./pages/Home";
export default function App() {
function computedClassName({ isActive }) {
return isActive ? "list-group-item alex" : "list-group-item";
}
return (
<div>
<div className="row">
<div className="col-xs-offset-2 col-xs-8">
<div className="page-header">
<h2>React Router Demo</h2>
</div>
</div>
</div>
<div className="row">
<div className="col-xs-2 col-xs-offset-2">
<div className="list-group">
{/* 路由链接 */}
<NavLink className={computedClassName} to="/about">
About
</NavLink>
<NavLink className={computedClassName} to="/home">
Home
</NavLink>
</div>
</div>
<div className="col-xs-6">
<div className="panel">
<div className="panel-body">
{/* 注册路由 */}
<Routes>
<Route path="/ABOUT" element={<About />} />
<Route path="/home" element={<Home />} />
<Route path="/" element={<Navigate to="/about" />} />
</Routes>
</div>
</div>
</div>
</div>
</div>
);
}
4. useRoutes 路由表
4.1 routes
/* src/routes/index.js */
import About from "../pages/About";
import Home from "../pages/Home";
import { Navigate } from "react-router-dom";
export default [
{
path: "/about",
element: <About />,
},
{
path: "/home",
element: <Home />,
},
{
path: "/",
element: <Navigate to="/about" />,
},
];
4.2 App.jsx
/* src/App.jsx */
import React from "react";
import { NavLink, useRoutes } from "react-router-dom";
import routes from "./routes";
export default function App() {
//根据路由表生成对应的路由规则
const element = useRoutes(routes);
return (
<div>
<div className="row">
<div className="col-xs-offset-2 col-xs-8">
<div className="page-header">
<h2>React Router Demo</h2>
</div>
</div>
</div>
<div className="row">
<div className="col-xs-2 col-xs-offset-2">
<div className="list-group">
{/* 路由链接 */}
<NavLink className="list-group-item" to="/about">
About
</NavLink>
<NavLink className="list-group-item" to="/home">
Home
</NavLink>
</div>
</div>
<div className="col-xs-6">
<div className="panel">
<div className="panel-body">
{/* 注册路由 */}
{element}
</div>
</div>
</div>
</div>
</div>
);
}
5. 嵌套路由
5.1 Home.jsx
/* src/pages/Home.jsx */
import React from "react";
import { NavLink, Outlet } from "react-router-dom";
export default function Home() {
return (
<div>
<h2>Home组件内容</h2>
<div>
<ul className="nav nav-tabs">
<li>
<NavLink className="list-group-item" to="news">
News
</NavLink>
</li>
<li>
<NavLink className="list-group-item" to="message">
Message
</NavLink>
</li>
</ul>
{/* 指定路由组件呈现的位置 */}
<Outlet />
</div>
</div>
);
}
5.2 Message.jsx
/* src/pages/Message.jsx */
import React from "react";
export default function Message() {
return (
<div>
<ul>
<li>
<a href="/message1">message001</a>
</li>
<li>
<a href="/message2">message002</a>
</li>
<li>
<a href="/message/3">message003</a>
</li>
</ul>
</div>
);
}
5.3 News.jsx
/* src/pages/News.jsx */
import React from "react";
export default function News() {
return (
<ul>
<li>news001</li>
<li>news002</li>
<li>news003</li>
</ul>
);
}
5.4 index.js
/* src/routes/index.js */
import About from "../pages/About";
import Home from "../pages/Home";
import Message from "../pages/Message";
import News from "../pages/News";
import { Navigate } from "react-router-dom";
export default [
{
path: "/about",
element: <About />,
},
{
path: "/home",
element: <Home />,
children: [
{
path: "news",
element: <News />,
},
{
path: "message",
element: <Message />,
},
],
},
{
path: "/",
element: <Navigate to="/about" />,
},
];
5.5 App.jsx
/* src/App.jsx */
import React from "react";
import { NavLink, useRoutes } from "react-router-dom";
import routes from "./routes";
export default function App() {
//根据路由表生成对应的路由规则
const element = useRoutes(routes);
return (
<div>
<div className="row">
<div className="col-xs-offset-2 col-xs-8">
<div className="page-header">
<h2>React Router Demo</h2>
</div>
</div>
</div>
<div className="row">
<div className="col-xs-2 col-xs-offset-2">
<div className="list-group">
{/* 路由链接 */}
<NavLink className="list-group-item" to="/about">
About
</NavLink>
<NavLink className="list-group-item" to="/home">
Home
</NavLink>
</div>
</div>
<div className="col-xs-6">
<div className="panel">
<div className="panel-body">
{/* 注册路由 */}
{element}
</div>
</div>
</div>
</div>
</div>
);
}