第九章 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>);
}