一、基本使用
1、安装
yarn add react-router-dom
2、导入路由的三个核心组件:Router/Route/Link/Routes
import {BrowserRouter as Router, Route, Link, Routes} from "react-router-dom"
3、使用Router组件 包裹整个应用
- 不需要加exact 精准匹配
- 需要用Routes包裹起来 。routers:只会匹配一个
// 导入组件
import { Route, Routes} from "react-router-dom"
const First = () => <p> 页面一的内容 </p>
const App = () => {
// 使用Router组件包裹整个应用
<Router>
<Routes>
<h1>React路由基础</h1>
{/* 指定路由入口 */}
<link to="/first">页面一</link>
{/* 指定路由出口 */}
<Route path="first" element={First} />
</Routes>
</Router>
}
二、路由嵌套
- 当匹配到父级组件时会自动渲染index属性的组件
- outlet: 父路由元素中使用
<Outlet>来渲染其子路由元素。这允许在呈现子路由时显示嵌套UI。
// 导入组件
import { Route, Routes} from "react-router-dom"
const First = () => <p> 页面一的内容 </p>
const LayoutRoot = () => {
return <div class="Layout">
<Outlet />
</div>
}
const App = () => {
// 使用Router组件包裹整个应用
<Router>
<Routes>
<Route path="/" element={<LayoutRoot />}>
<Route index element={<Home />}</Route>
{/* 会默认继承父级的path '/' */}
<Route path="bar" element={<Home />}</Route>
</Route>
<Route path="first" element={<First />} />
</Routes>
</Router>
}
三、编程式跳转
1、普通跳转
// 导入组件
import {BrowserRouter as Router, Route, Link} from "react-router-dom"
import { useNavigate, useParams } from "react-router-dom";
const Home = () => <p> 页面一的内容 </p>
// 函数组件路由跳转
const Login = () => {
const loginHandle = ()=>{
// 使用编程式导航实现路由跳转
useNavigate('/home')
}
render() {
return (
<div>
<p>登录页面:</p>
<button onClick={this.handleLogin}></button>
</div>
)
}
}
const App = () => {
// 使用Router组件包裹整个应用
<Router>
<Routes>
<h1>React路由基础</h1>
<Login></Login>
<Route path="/Home" element={<Home />} />
</Routes>
</Router>
}
ReactDOM.render(<App />,document.getElementByID('root'))
2、动态路由
创建
const App = () => {
// 使用Router组件包裹整个应用
<Router>
<Routes>
<h1>React路由基础</h1>
<Route path="/Detail/:id" element={<Detail />} />
</Routes>
</Router>
}
使用
// 导入组件
import {BrowserRouter as Router, Route, Link} from "react-router-dom"
import { useNavigate, useParams } from "react-router-dom";
// 发送数据 编程式
const Home = () => {
const goAbout = () => {
useNavigate('/About/1')
}
return (
<div>
<button onClick={goAbout}>动态路由</button>
</div>
)
// 发送数据 声明式
<Link to={`/about/1`}>Child2</Link>
// 接收数据
function Detail = () => {
const BlogList = {
1: {
title:"第一篇文章",
description: "关于Vue 3.0v的"
},
2: {
title:"第二篇文章",
description: "关于React 18.0.0v的"
}
}
const { id } = useParams();
const {title,description} =BlogList[id]
return (
<div>
<h2>{ title }</h2>
<h2>{ description }</h2>
</div>
)
}
3、查询参数跳转
发送
// 发送参数 声明式
<Link className="nav" to={`/bar?page=3&size=10&usename=list`}>Child2</Link>
// 发送数据 编程式
const Home = () => {
const goBar = () => {
useNavigate('/bar?page=3&size=10&usename=list')
}
return (
<div>
<button onClick={goBar}>查询参数</button>
</div>
)
接收
// 导入组件
import {BrowserRouter as Router, Route, Link} from "react-router-dom"
import { useSearchParams } from "react-router-dom";
// 带参数详情组件
function Bar = () => {
const [searchParams,setSearchParams] = useSearchParams()
console.log(searchParams.get('page')) // '3'
console.log(searchParams.get('pageSize')) // '10'
console.log(searchParams.getAll('usename')) // [ 'list' ]
return <div>Bar组件</div>
}
const App = () => {
// 使用Router组件包裹整个应用
<Router>
<Routes>
<h1>React路由基础</h1>
<Route path="/Bar" element={<Bar />} />
</Routes>
</Router>
}
ReactDOM.render(<App />,document.getElementByID('root'))
4、state参数
发送
//路由传参 声明式
<Link
className="nav"
to={`/Detail`}
state={{name:'tom',age:"20"}}
>
Child2
</Link>
// 发送数据 编程式
const Home = () => {
const goDetail = () => {
useNavigate('/Detail', { state: {name:'tom',age:"20"} })
}
return (
<div>
<button onClick={goDetail}>state参数</button>
</div>
)
接收
import { useLocation } from "react-router-dom";
const Detail = () => {
const { name, age } = useLocation()
return (
<div>{name}</div>
<div>{age}</div>
)
}
export default Detail
四、配置路由规则
router/index.js
import { lazy } from "react"
// 导入组件
import { Route, Routes} from "react-router-dom"
// import Bar form "./view/Bar";
const Bar = lazy(() => import('./view/Bar'))
// import Home form "./view/Home";
const Home = lazy(() => import('./view/Home'))
// 这个layout不要懒加载 有闪屏
import LayoutRoot form "./view/LayoutRoot";
const lazyLoad =(children) => {
return <Suspense fallback={<span>loading</span>}>{children}</Suspense>
}
const router = [
{
path: '/',
element: <LayoutRoot />,
children: [
{
index: true,
element: lazyLoad(<Home />)
},
{
path:"bar",
element: lazyLoad(<Bar />)
}
]
}
]
export default router
App.js
import { Suspense } from "react"
import { useRoutes } from "react-router-dom"
import router from "./router"
function App() {
return useRoutes(router)
}
// 相当于这样
const App = () => {
// 使用Router组件包裹整个应用
<Router>
<Routes>
<Route path="/" element={<LayoutRoot />}>
<Route index element={<Home />}</Route>
{/* 会默认继承父级的path '/' */}
<Route path="bar" element={<Bar />}</Route>
</Route>
</Routes>
</Router>
}