一、安装依赖
yarn add react-router-dom@5.3.0
二、使用
- react路由有两种
- hash路由:HashRouter
- history路由:BrowserRouter
- 路由组件
- Link:导航路由
- NavLink:导航路由,可以添加高亮显示
- Route:定义路由,即要跳转的路由
- path:路由的路径
- component:路由对应的组件
- exact:路由精确匹配(当路径为 / 时,要使用 精确匹配
// 引入路由配置
// HashRouter hash 路由
// import { HashRouter as Router, Link, Route } from "react-router-dom";
// BrowserRouter history 路由,使用html5 的 history Api,history.pushState()
import { BrowserRouter as Router, Link, Route } from "react-router-dom";
import Home from "./Home";
import Comment from "./Comment";
import Info from "./Info";
const App = () => {
return (
// 在顶级组件用react路由提供的组件包裹,写一次就可以,无需在每个路由的地方重复写
<Router>
<div>
{/* 定义路由link,Link组件解析后变成 a 标签 */}
<Link to="/" exact>首页</Link>
<Link to="/comment" exact>评论</Link>
<Link to="/info" exact>个人信息</Link>
</div>
<div>
{/* 定义路由配置 */}
<Route path="/" exact>
<Home></Home>
</Route>
{/* 组件可以使用component 参数 传递 */}
<Route path="/comment" component={Comment}></Route>
<Route path="/info" component={Info}></Route>
</div>
</Router>
);
};
export default App;
注意:若 / 路径不使用精确匹配 exact,则会出现在 /comment路径时,也会匹配到 / 路径
三、路由选中高亮显示NavLink
// 引入路由配置
import { BrowserRouter as Router, Route, NavLink } from "react-router-dom";
import Home from "./Home";
import Comment from "./Comment";
import Info from "./Info";
// 引入样式
import "./App.css";
const App = () => {
return (
<Router>
<div className="nav">
{/* 定义路由NavLink,NavLink组件解析后变成 a 标签 */}
{/* NavLink 路由对应的 a 标签,会 自动添加 active 类名,可以通过该类名进行自定义样式 */}
<NavLink to="/home">首页</NavLink>
<NavLink to="/comment">评论</NavLink>
<NavLink to="/info">个人信息</NavLink>
</div>
<div>
<Route path="/home">
<Home></Home>
</Route>
<Route path="/comment" component={Comment}></Route>
<Route path="/info" component={Info}></Route>
</div>
</Router>
);
};
export default App;
/* App.css */
.nav a {
text-decoration: none;
margin-right: 10px;
color: skyblue;
}
.nav a.active {
color: red;
}
四、Switch组件的使用
- 在vue中可以通过 * 通配符进行 404 路由匹配
- 在react中,则可以通过 Switch 组件实现
- Switch 组件 可以简单理解为 仅匹配一次,只要匹配到了就不会再往下匹配
// 引入路由配置
import {
BrowserRouter as Router,
Route,
NavLink,
Switch,
} from "react-router-dom";
import Home from "./Home";
import Comment from "./Comment";
import Info from "./Info";
import NotFound from "./404";
// 引入样式
import "./App.css";
const App = () => {
return (
<Router>
<div className="nav">
<NavLink to="/" exact>
首页
</NavLink>
<NavLink to="/comment" exact>
评论
</NavLink>
<NavLink to="/info" exact>
个人信息
</NavLink>
</div>
<div>
<Switch>
<Route path="/" exact>
<Home></Home>
</Route>
<Route path="/comment" component={Comment}></Route>
<Route path="/info" component={Info}></Route>
<Route component={NotFound}></Route>
</Switch>
</div>
</Router>
);
};
export default App;
五、嵌套路由
- 即在子组件中继续使用路由嵌套
5.1 改造 评论页面
// Comment.js
import { Route, NavLink } from "react-router-dom";
import CommentA from "./Comm/ComA";
import CommentB from "./Comm/ComB";
function Comment() {
return (
<div>
<div>
<h2>这里是评论</h2>
<NavLink to="/comment/a">CommentA</NavLink>
<NavLink to="/comment/b" style={{ marginLeft: "20px" }}>
CommentB
</NavLink>
</div>
<div>
<Route path="/comment/a" component={CommentA}></Route>
<Route path="/comment/b">
<CommentB></CommentB>
</Route>
</div>
</div>
);
}
export default Comment;
5.2 新增 评论 子页面A和B
// ComA.js
function CommentA() {
return <div>这里是评论A</div>;
}
export default CommentA;
// ComB.js
function CommentB() {
return <div>这里是评论B</div>;
}
export default CommentB;
5.3 效果
六、编程式导航
- 使用 useHistory 实现 路由导航 切换
代码如下:
import { Route, NavLink, useHistory } from "react-router-dom";
import CommentA from "./Comm/ComA";
import CommentB from "./Comm/ComB";
function Comment() {
// 引入路由 hook
const history = useHistory();
return (
<div>
<div>
<h2>这里是评论</h2>
<NavLink to="/comment/a">CommentA</NavLink>
<NavLink
to="/comment/b"
style={{ marginLeft: "20px", marginRight: "20px" }}
>
CommentB
</NavLink>
<button
onClick={() => {
// 编程式导航
console.log("history", history);
// 跳转首页,有历史记录
// history.push("/");
// 跳转首页,没有历史记录,即无法使用浏览器回退键返回
history.replace("/");
}}
>
跳转首页
</button>
</div>
<div>
<Route path="/comment/a" component={CommentA}></Route>
<Route path="/comment/b">
<CommentB></CommentB>
</Route>
</div>
</div>
);
}
export default Comment;
七、路由传参
7.1 改造 index.js
import React from "react";
import { createRoot } from "react-dom/client";
import store from "./store";
import App from "./App";
import { Provider } from "react-redux";
// 引入路由 最顶级组件包裹
import { BrowserRouter as Router } from "react-router-dom";
const root = createRoot(document.getElementById("root"));
root.render(
<Router>
<Provider store={store}>
<App></App>
</Provider>
</Router>
);
7.1 改造 App.js
// 引入路由配置
import { Route, NavLink, Switch, useHistory } from "react-router-dom";
import Home from "./Home";
import Comment from "./Comment";
import Info from "./Info";
import NotFound from "./404";
// 引入样式
import "./App.css";
const App = () => {
// 路由 hook
const history = useHistory();
console.log("history", history);
return (
<div>
<div className="nav">
<NavLink to="/" exact>
首页
</NavLink>
<NavLink to="/comment" exact>
评论
</NavLink>
<NavLink to="/info">个人信息</NavLink>
<button
onClick={() => {
console.log("history", history);
history.push("/info/666");
}}
>
跳转个人信息页,带参数
</button>
</div>
<div>
<Switch>
<Route path="/" exact>
<Home></Home>
</Route>
<Route path="/comment" component={Comment}></Route>
{/* 修改路由 */}
<Route path="/info/:id" component={Info}></Route>
<Route component={NotFound}></Route>
</Switch>
</div>
</div>
);
};
export default App;
7.3 效果
- 若不传参数
- 传参数
7.4 改造个人信息组件,获取路由参数
import { useParams } from "react-router-dom";
function Info() {
// 使用 hook
const params = useParams();
console.log("路由参数", params);
return (
<div>
<h2>这里是个人信息</h2>
</div>
);
}
export default Info;