react路由
- 现代的前端应用大多都是 SPA(单页应用程序),也就是只有一个 HTML 页面的应用程序。因为它的用户体验更好、对服务器的压力更小,所以更受欢迎。为了有效的使用单个页面来管理原来多页面的功能,前端路由应运而生
- 前端路由是一套映射规则,在React中,是 URL路径 与 组件 的对应关系
react-router-dom
- React实现页面路由的模块:react-router-dom
路由器组件:< HashRouter > < BrowserRouter >
- HashRouter
- hash模式
- 全局路由切换
- BrowserRouter
- history模式
- 单页面的路由切换
- hash 路由和 history 路由的区别:
- 原理不同: hash 路由是通过监听 hashChange 事件实现;history路由是通过 调用 history.pushState 方法 和监听 popState 事件实现
- 表现方式不同:hash 路由前面带 # ;history路由没有
- history路由在页面刷新的时候可能会有白屏的情况;因为刷新后浏览器会向服务器发送这个地址的请求,但文件资源并不存在,会报404错误;需要后端做一个保底映射,所有的请求全部拦截到index.html上。
- 使用方式:
//例如:
import {
// HashRouter as Router, // hash模式
BrowserRouter as Router, // history模式
Route,
Switch,
} from 'react-router-dom'
import Home from '../containers/home'
const BasicRouter = () => (
<Router>
<Switch>
<Route exact path="/" component={Home} />
</Switch>
</Router>
)
export default BasicRouter
Route 标签:定义具体组件
- 语法:
//v5版本:
<Route path="/xx/xx" component={组件}></Route>
//v6:
<Route path="/xx/xx" element={<组件名/>}/>
- v5以及其他老版本:
- 当路由为 / 时,默认模糊匹配;这样可能会存在匹配到多个的问题
- 用 Switch 标签包裹之后:按顺序 自上而下 匹配
- exact 属性可以设置为精准匹配
- v6版本:
- 默认 精准匹配;匹配完整路径;
- 不需要Switch 标签、exact 属性
- 若要匹配某一部分,则在路径后面加 /*
- 可以将path 设置为 *,用于实现 404页面
Link 标签、NavLink标签
- 类似 a 标签,用于跳转
- NavLink:可以设置激活状态的样式
- 老版本:可以通过 activeClassName 或 activeStyle 设置
- v6:可以通关箭头函数 接收isActive
Navigate 组件
- 用于重定向
- 老版本:Redirect 标签重定向
import { Navigate } from "react-router-dom";
function A() {
return <Navigate to="/b" />;
}
useNavigate 编程式路由跳转
- 可以通过 JS 代码完成路由跳转
- useNavigate取代了原先版本中的useHistory
- 可以直接传入要跳转的目标路由
import { useNavigate } from 'react-router-dom';
function Foo(){
const navigate = useNavigate();
return (
// 上一个路径:/a; 当前路径: /a/a1
<div onClick={() => navigate('/b')}>跳转到/b</div>
<div onClick={() => navigate('a11')}>跳转到/a/a1/a11</div>
<div onClick={() => navigate('../a2')}>跳转到/a/a2</div>
<div onClick={() => navigate(-1)}>跳转到/a</div>
)
}
动态路由参数
useParams 获取路径参数
- 在Route组件中的path属性中定义路径参数
- 在组件内通过useParams hook 访问路径参数
<BrowserRouter>
<Routes>
<Route path="/foo/:id" element={<Foo />} />
</Routes>
</BrowserRouter>;
import { useParams } from "react-router-dom";
export default function Foo() {
const params = useParams();
return (
<div>
<h1>{params.id}</h1>
</div>
);
}
useSearchParams 访问和修改查询参数
- 使用 useSearchParams hook 来访问和修改查询参数。其用法和 useState 类似,会返回当前对象和更改它的方法
- 使用 setSearchParams 时,必须传入所有的查询参数,否则会覆盖已有参数
import { useSearchParams } from "react-router-dom";
// 当前路径为 /foo?id=12
function Foo() {
const [searchParams, setSearchParams] = useSearchParams();
console.log(searchParams.get("id")); // 12
setSearchParams({
name: "foo",
}); // /foo?name=foo
return <div>foo</div>;
}
路径匹配规则
- 当URL同时匹配到含有路径参数的路径和无参数路径时,优先匹配没有参数的”具体的“(specific)路径。
<Route path="teams/:teamId" element={<Team />} />
<Route path="teams/new" element={<NewTeamForm />} />
//如上的两个路径,将会匹配 teams/new
History 对象
- v5等之前老版本:useHistory
- v6+ : useNavigate取代了原先版本中的useHistory
- 路由跳转可以通过 useNavigate 实现
- 在路由中传递参数也可以通过 useNavigate 实现
- state:用于记录用户的跳转详情 、或在跳转时携带信息;不显示在页面上,不会引起刷新,只由开发人员操作
//通过路由传参
let navigate = useNavigate();
navigate("/users/123", { state: partialUser })
//在目标的组件中,可以用 useLocation 方法获取该对象
let location = useLocation();
console.log(location.state)
参考来源:https://zhuanlan.zhihu.com/p/431389907