一、基本使用
1. 依赖安装
npm i react-router-dom
2. 引入组件
import { BrowserRouter, Routes, Route } from "react-router-dom"
import Foo from "./Foo"
import Bar from "./Bar"
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/foo" element={<Foo />} />
<Route path="/bar" element={<Bar />} />
</Routes>
</BrowserRouter>
)
}
需要注意, <Route path="/foo" element={Foo} /> 是错误写法。
二、路由跳转
在跳转路由时,如果路径是/开头的则是绝对路由,否则为相对路由,即相对于当前 URL进行改变
1. Link与NavLink跳转
Link跳转
import { Link } from "react-router-dom"
<Link to="foo">to foo</Link>
// 下面是to属性的几种用法
// to: Object
<Link
to={{
pathname: '/courses',
search: '?sort=name',
hash: '#the-hash',
state: { fromDashboard: true }
}}
/>
// to: string
<Link to="/courses?sort=name" />
// to: function
<Link to={location => ({ ...location, pathname: "/courses" })} />
<Link to={location => `${location.pathname}?sort=name`} />
NavLink跳转
import { NavLink } from "react-router-dom"
function Foo() {
return (
<NavLink style={({ isActive }) => ({ color: isActive ? "red" : "#fff" })}>
Click here
</NavLink>
);
}
v6移除了v5的activeClassName属性,现在如果要根据当前路由修改样式,可以按照如下方式:
{/* className 写法 */}
<NavLink
className={({isActive}) => {
return isActive ? "highlight" : "";
}}
to="home">Home</NavLink>
{/* style 写法 */}
<NavLink
to="about"
style={({isActive}) => {
return {
color: isActive ? "red" : ""
}
}}
>About</NavLink>
2. 编程式跳转
在v6中,useNavigate取代了v5的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>
)
}
三、 动态路由参数
1. 路由的定义
<BrowserRouter>
<Routes>
<Route path="/foo/:id" element={<Foo />} />
</Routes>
</BrowserRouter>;
2. 参数的获取
useParams
import { useParams } from "react-router-dom";
export default function Foo() {
const params = useParams();
return (
<div>
<h1>{params.id}</h1>
</div>
);
}
需要注意的是,当URL同时匹配到含有路径参数的路径和无参数路径时,优先匹配没有参数的路径。例如,url为"/foo/asdf",存在<Route path="foo/:id" element={<Team />} />与 <Route path="foo/asdf" element={<NewTeamForm />} />两个路由时,优先匹配后面的路由。
useSearchParams
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>;
}
setSearchParams方法会覆盖原有的参数,使用时需要注意。
四、嵌套路由
详细可参考此博客
五、默认路由
在嵌套路由中,如果 URL 仅匹配了父级 URL,则Outlet中会显示带有index属性的子路由。
<Routes>
<Route path="/foo" element={Foo}>
<Route index element={Default}></Route>
<Route path="bar" element={Bar}></Route>
</Route>
</Routes>
- 当 url 为/foo时:Foo 中的 Outlet 会显示 Default 组件
- 当 url 为/foo/bar时:Foo 中的 Outlet 会显示为 Bar 组件
六、路由重定向
移除了v5的Redirect组件
import { Navigate, Route, Routes } from 'react-router-dom';
function App() {
return (
<Routes>
<Route path='/' element={<Navigate replace to="/home" />} />
</Routes>
);
}
七、一些常用Hooks
| Hooks名 | 作用 |
|---|---|
| useParams | 返回当前参数 |
| useNavigate | 返回当前路由 |
| useOutlet | 返回根据路由生成的element |
| useLocation | 返回当前的location 对象 |
| useRoutes | 同Routers组件一样,只不过是在js中使用 |
| useSearchParams | 用来匹配URL中?后面的搜索参数 |