介绍
react框架本身不带路由功能,使用路由之前需要先安装,react提供了两个包,分别是React-router 与 React-router-dom ,他们的区别如下:
React-router: 提供了router的核心api。如Router、Route、Switch等,但没有提供有关dom操作进行路由跳转的api;
React-router-dom: 提供了BrowserRouter、Route、Link等api,可以通过dom操作触发事件控制路由。
react-router-dom是在react-router的基础上开发的,react-router-dom中很多组件都是直接从react-router中直接导出的。所以安装了react-router-dom后就不用再安装react-router;
安装
使用 npm 安装
npm install react-router-dom@6 //这里安装的是第六版
使用 yarn 安装
yarn add react-router-dom@6 //这里安装的是第六版
路由组件
react路由中提供了两种路由组件模式,分别是 BrowserRouter是history模式路由。
BrowserRouter 路由长这样
http://abc.com/xxx
,是通过浏览器的 history.pushState 和history.popState 实现,可能会有一定兼容性,低版本的浏览器不支持,比如ie,部署到服务器上需要进行一定的配置。HashRouter 是hash模式路由,路由长这样
http://abc.com#/xxx
,浏览器通过监听hashchange来改变路由的,兼容性良好。
无论是 BrowserRouter 路由还是 HashRouter 路由在使用的时候,都是需要用来包住其他组件,在react项目中,通常用于包裹最外层的组件,这样整个项目的子组件都可以使用。
BrowserRouter(history模式)
import { BrowserRouter } from "react-router-dom";
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<BrowserRouter>
<React.StrictMode>
<App />
</React.StrictMode>
</BrowserRouter>
);
HashRouter(hash模式)
import { HashRouter } from "react-router-dom";
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<HashRouter>
<React.StrictMode>
<App />
</React.StrictMode>
</HashRouter>
);
声明式导航
Link
Link 用于用户点击跳转指定路径,在react-router-dom中 Link 会被解析成 <a/>
标签。
import React from "react";
import { Link } from "react-router-dom";
const Router: React.FC = () => {
return (
<div>
<Link to="home">
首页
</Link>
</div>
);
};
export default Router;
例如:当点击首页的 Link 组件时,会跳转到到对应的路径
Link注意事项
这里的to的值不以 /
开头代表相对于父路由解析。
假如我们设置了父路由为weixin
,配置Link是 <Link to="home"> 首页 <Link>
时,点击后的路径是:
反之,如果配置的是 <Link to="/home"> 首页 <Link>
时,点击后的路径是:
Link传参
在 Link 中传递的参数可以存放在 state 中,该值会存放在 history state 中,可以使用useLocation()访问当前的参数。
import React from "react";
import { Link, useLocation, Routes, Route } from "react-router-dom";
const Home = () => {
const { state } = useLocation();
console.log(state.gift);
return <div>Home {state.gift}</div>;
};
const Router: React.FC = () => {
return (
<div>
<Link to="home" key="home" state={{ gift: "兰博基尼" }}>
首页
</Link>
<Routes>
<Route path="home" element={<Home />} />
</Routes>
</div>
);
};
export default Router;
NavLink
NavLink 是一种特殊的 Link ,区别就是 NavLink 知道自己是否处于 ‘挂起’ 的状态,常用于构建导航菜单使用。
<nav id="sidebar">
<NavLink to="/messages" />
</nav>
#sidebar a.active {
color: red;
}
Routes
React Router v6 引入了一个名为 Routes 的组件,它有点像 Switch 。
在v5中的写法是:
import React from "react";
import { Route, Switch } from "react-router-dom";
const About = () => {
return <div>About</div>;
};
const Error = () => {
return <div>当前页面不存在</div>;
};
const Router: React.FC = () => {
return (
<div>
<Switch>
<Route path="about">
<About />
</Route>
<Route path="*">
<Error />
</Route>
</Switch>
</div>
);
};
export default Router;
在v6中的写法
import React from "react";
import { Route, Routes } from "react-router-dom";
const About = () => {
return <div>About</div>;
};
const Error = () => {
return <div>当前页面不存在</div>;
};
const Router: React.FC = () => {
return (
<div>
<Routes>
<Route path="about" element={<About />} />
<Route path="*" element={<Error />} />
</Routes>
</div>
);
};
export default Router;
编程式导航
useNavigate
在v6中提供了 useNavigate
hook函数用于编程式导航,useNavigate
返回一个函数,接收两个参数,第一个是路径,第二个是传递的状态。
import React from "react";
import {
Route,
Routes,
useLocation,
useNavigate,
} from "react-router-dom";
import { Button } from "antd";
const Find = () => {
const { state } = useLocation();
return <div>Find {state.find}</div>;
};
const Router: React.FC = () => {
const navigate = useNavigate();
const toFind = () => {
navigate("find", { state: { find: "发现更多" } });
};
return (
<div>
<Button type="primary" onClick={toFind}>
跳转发现页面
</Button>
<Routes>
<Route path="find" element={<Find />} />
</Routes>
</div>
);
};
export default Router;
这里对于传递的参数,可以使用 useLocation
获取。