react-router-dom
官方文档: https://reactrouter.com/docs/en/v6/api#routing
安装
安装当前最新版本:
yarn add react-router-dom
or:
安装指定版本:
yarn add react-router-dom@6
web相关API
- BrowserRouter
- HashRouter
- Link
- NavLink
- Navigate
- OutLet
- useOutletContext
- Router
- Routes & Route
- generatePath
- history
- useNavigate
- useParams
- useRoutes
matchPath matchRoutes createRoutesFromChildren useResolvedPath useHref useLocation useNavigationType useLinkClickHandler resolvePath useSearchParams
简单介绍
react-router包含了绝大多数的路由方法。
react-router-dom包含了react-router和额外的方法。
react-router-dom = react-router+ <BrowserRouter> + <HashRouter> + <Link>
<xxxRouter> 有很多种,在web浏览器中,我们选择<BrowserRouter> 或<HashRouter>
批量解释
BrowserRouter(官方推荐 )
BrowserRouter存储了地址栏信息和导航。
用法
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router } from "react-router-dom";
ReactDOM.render(
<Router>
{}
</Router>,
root
);
HashRouter(官方不推荐使用 )
当特定的URL因为某些原因不能或不应该发送到服务器时,使用HashRouter。
官方文档提示:我们强烈建议你不要使用HashRouter,除非你完全无法避免使用它
Link
对应生成一个<a href> 标签。可以在任何地方使用
语法
import {Link} from 'react-router-dom'
<Link to='/url'>xxx</Link>
or:
import {Link} from 'react-router-dom'
<Link to='url'>xxx</Link>
假定当前地址栏完整路径是http://localhost:3000/demo ,
-
第一种带/ 的写法, 点击会跳转到父路径/url 即跳转到http://localhost:3000/url -
第二种不带/ 的写法, 点击会跳转到当前路径/url 此时,/url 就是当前路径的子路径 即跳转到http://localhost:3000/demo/url
NavLink
是一种特殊的Link,通常用作面包屑或tab栏导航,
NavLink会显示出当前哪个选项被点击或选择了。
NavLink有两个属性,即style 和className ,二选一
style代表行内样式,className代表外联样式。
用于显示被点击后的样式。
语法
import {NavLink} from 'react-router-dom'
<NavLink
to="tab1"
style={({isActive}) => isActive ? activeStyle : undefined}>tab1</NavLink>
or:
import {NavLink} from 'react-router-dom'
<NavLink
to="tab1"
className={({isActive}) => isActive ? activeClassName : undefined}>tab1</NavLink>
Navigate
替换导航。
Navigate会把当前地址栏的地址,替换成Navigate组件中to后面的新地址。
语法
import { Navigate } from 'react-router-dom';
<Navigate to='/url' />
demo
import React, {useState} from 'react';
import { Navigate } from 'react-router-dom';
function Demo4() {
const [isClick, setClick] = useState(false);
const handleClick = () => {
setClick(true);
}
return (
<div>
<div>hello demo4 !</div>
<div>
<button onClick={handleClick}>click to /</button>
</div>
{isClick && (<Navigate to='/' />)}
</div>
)
}
export default Demo4;
OutLet
放在父组件里,用来告诉浏览器,在渲染的时候,
-
如果路由匹配到父路由,就渲染父组件 -
如果路由匹配到子路由,就渲染子路由
demo
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import { Child1, Child2, Demo5 } from './demo5';
function App() {
return (
<Routes>
<Route path='/demo5' element={<Demo5 />}>
<Route path='child1' element={<Child1 />} />
<Route path='child2' element={<Child2 />} />
</Route>
</Routes>
)
}
render(
<Router>
<App />
</Router>,
document.querySelector('#root')
);
import React from 'react';
import { Outlet } from 'react-router-dom';
export function Child1() {
return (
<div>
hello, child 1111 !
</div>
)
}
export function Child2() {
return (
<div>
hello, child 2222 !
</div>
)
}
export function Demo5() {
return (
<div>
hello, demo 555 !
{}
<Outlet />
</div>
)
}
useOutletContext()
把父组件的状态传给子组件使用。
Router
一般会用作BrowserRouter 或HashRouter 引入时的缩写
然后在书写时,用Router替代BrowserRouter或HashRouter
demo
import {BrowserRouter as Router} from 'react-router-dom';
Routes & Route
两者都是基于当前路径去渲染react路由的一种基础方式。
Routes是用来包裹住Route的。就是之前版本的Switch
Route之间还可以做嵌套,形成父子路由。
demo
import {Routes, Route} from 'react-router-dom';
<Routes>
<Route path='/demo5' element={<Demo5 />}>
<Route path='child1' element={<Child1 />} />
<Route path='child2' element={<Child2 />} />
</Route>
</Routes>
generatePath()
generatePath 衍生路径,也可以叫生成路径
它接收一个路径和一个参数值,然后生成一个新的路径
demo
import {generatePath} from 'react-router-dom';
console.log(generatePath("/users/:id", { id: 42 }));
console.log(generatePath("/files/:type/*", {
type: "img",
"*": "cat.jpg"
}));
history
history库是react路由的唯一依赖,很多react路由中的方法都是直接取自于history库,
比如Location , To , Path , State 等。
history库需要单独安装和学习。
useNavigate
react-router-dom@6取消了重定向方法
而useNavigate可以做重定向
语法:
import { useNavigate } from "react-router-dom";
function Demo() {
let navigate = useNavigate();
const handleClick = () => {
navigate('/url', { replace: true });
}
return (
<div>
<button onClick={handleClick}>click to redirect</button>
</div>
)
}
useParams
用来在对应子路由中获取动态子路由的参数值
动态路由形式:
path=':userId'
demo
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import Demo6 from './demo6';
render(
<Router>
<Demo6 />
</Router>,
document.querySelector('#root')
);
import React from 'react';
import { Routes, Route, useParams } from 'react-router-dom';
function Child1() {
let { userId } = useParams();
console.log(userId);
return (
<div>hello , child1 !</div>
)
}
function Child2() {
return (
<div>
hello, child 2222 !
</div>
)
}
function Demo6() {
return (
<Routes>
<Route path="/demo6">
<Route path=":userId" element={<Child1 />} />
<Route path="me" element={<Child2 />} />
</Route>
</Routes>
)
}
export default Demo6;
比如 路径为: http://localhost:3000/demo6/hello
userId就是’hello’
比如 路径为: http://localhost:3000/demo6/2333
userId就是’2333’
注意: 用useParams 时,没有使用OutLet,也成功匹配了子路由
useRoutes
路由的另一种写法
就是把嵌套形式的路由,改成函数形式的路由
具体用哪一种,看个人喜好了。
这里写的demo中有点问题,
就是输入子路由之后,并没有渲染子组件。
目前还没有找到合适的方法去解决, 如果有知道的,欢迎评论讨论。
demo
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import Demo7 from './demo7';
render(
<Router>
<Demo7 />
</Router>,
document.querySelector('#root')
);
import React from 'react';
import { useRoutes } from 'react-router-dom';
function R() {
return (
<div>R </div>
)
}
function R1() {
return (
<div>R1 </div>
)
}
function R2() {
return (
<div>R2 </div>
)
}
function C1() {
return (
<div>这里是C1 </div>
)
}
function C2() {
return (
<div>这里是C2 </div>
)
}
function Demo7() {
let element = useRoutes([
{path: '/', element: <R />},
{
path: 'r1',
element: <R1 />,
children: [
{
path: 'c1',
element: <C1 />
},
{
path: 'c2',
element: <C2 />
},
]
},
{ path: 'r2', element: <R2 /> },
])
return element;
}
export default Demo7;
|