文章目录
1.什么是路由
- 一个路由就是一个映射关系(key:value)
- key为路径,value可能是function或component
2.路由分类
- web ( PC端 )
- native(react native)
- anywhere (其他)
3.react-router-dom的理解
-
react的一个插件库。
-
专门用来实现一个SPA应用。
-
基于react的项目基本都会用到此库。
4. react-router-dom相关API
-
BrowserRouter
-
HashRouter
-
Route
-
Redirect
-
Link
-
NavLink
-
Switch
5.其他
-
history对象
-
match对象
-
withRouter函数
6. react-router5 路由基本使用
1.效果
react-router5
2.代码
App.js一级路由
注意:
- activeClassName 为当前激活的样式类名,demo 提前在 public 中的 index.html 中定义好
封装的路由 NavLink
// 封装后的 NavLink
function MyLink(props){
return <NavLink activeClassName='demo' {...props} />
}
App.jsx
import { Route, Switch,Redirect, BrowserRouter, Switch, Redirect } from 'react-router-dom'
import About from './about/index'
import Home from './home/index'
export default function App() {
return (
<BrowserRouter>
<div>
<div> header </div>
<div style={{ flex: 1, fontSize: '32px' }} >
<MyLink to={'/about'} >about</MyLink>
<br />
<MyLink to={'/home'} >home</MyLink>
</div>
<div style={{ flex: 7, fontSize: '32px' }} >
<Switch>
<Route to={'/about'} component={About} />
<Route to={'/home'} component={Home} />
<Redirect to={'home'} />
</Switch>
</div>
</div>
</BrowserRouter>
)
}
home.js下的二级路由
注意:因为根组件 App.js 已被 BrowserRouter 包裹,所以这里不需要用 BrowserRouter 再次包裹路由
import React from 'react'
import MyLink from '../com'
import Message from './message'
import New from './new'
import { Route, Redirect } from 'react-router-dom'
export default function Home() {
return (
<div >
<h1>
<MyLink to="/home/message" >message</MyLink>
<MyLink to="/home/new" >new</MyLink>
</h1>
<div>
<Route path="/home/message" component={Message} />
<Route path="/home/new" component={New} />
<Redirect to="/home/message" />
</div>
</div>
)
}
7.路由传参的三种方式
-
params
Link
let name = '张三' let age = 18 <Link to=`/home/${name}/${age}` />
Route
<Route path="/home/:title/:age" />
conponent 接收
let { title, age } = props.match.params
-
query
Link
<Link to=`/home?name='zhangsan'&age=18` />
Route
<Route path="/home" />
conponent 接收
import qs from 'querystring' let res = qs.parse(props.location.search.slice(1))
-
state
Link
<Link to={{ pathname: '/home', state: { title:"zhangsan", age:18 } }} />
Route
<Route path="/home" />
conponent 接收
let {age,title} = props.location.state
8.react-router6 基本使用
useRoutes 为路由表,可通过数组的形式进行嵌套配置
1.一级路由
app.js
import React, { useState } from 'react'
import { Route, Routes, Navigate, useRoutes } from 'react-router-dom'
import About from './about/index'
import Home from './home/index'
import Header from './Header/index'
import Message from './home/message'
import New from './home/new'
import Detail from './home/detail'
export default function Index() {
let element = useRoutes([
{
path: '/about',
element: <About />
},
{
path: '/home',
element: <Home />,
children: [
{
path: 'message',
element: <Message />,
children: [
// search, state 参数
{
path: 'detail',
element: <Detail />,
}
]
},
{
path: 'new',
element: <New />,
}
]
},
{
path: '/',
element: <Navigate to="/home" />
}
])
return (
<div>
<Header />
<div style={{ display: "flex" }} >
<div style={{ flex: 1, fontSize: '32px' }} >
<Link to={'/about'} >about</Link>
<br />
<Link to={'/home'} >home</Link>
</div>
<div style={{ border: "10px solid red", padding: '20px', flex: 7 }} >
{element}
</div>
</div>
</div >
)
}
2.二级路由
home.js
import React from 'react'
import Message from './message'
import New from './new'
import { Route, Navigate, Routes, Outlet, NavLink } from 'react-router-dom'
export default function Home() {
return (
<div >
<h1>
<NavLink to="message" >Message</NavLink>
<NavLink to="new" >New</NavLink>
</h1>
<div>
{/* <Routes>
<Route path={'/home/message'} element={<Message />} />
<Route path={'/home/new'} element={<New />} />
<Route path={'/home/message'} element={<Navigate to={'/home/message'} />} />
<Redirect to="/home" />
</Routes> */}
// 路由出口
<Outlet />
</div>
</div>
)
}
3.hooks
useRoutes
路由表
import { useRoutes } from 'react-router-dom'
// 导入组件
import About from './about/index'
import Home from './home/index'
import Message from './home/message'
import New from './home/new'
import Detail from './home/detail'
export default function Index() {
// 定义路由表
let element = useRoutes([
{
path: '/about',
element: <About />
},
{
path: '/home',
element: <Home />,
children: [
{
path: 'message',
element: <Message />,
children: [
{
path: 'detail',
element: <Detail />,
}
]
}
]
},
{
path: '/',
element: <Navigate to="/home" />
}
])
return (
<div>
<div style={{ display: "flex" }} >
<div style={{ flex: 1, fontSize: '32px' }} >
<Link to={'/about'} >about</Link>
<br />
<Link to={'/home'} >home</Link>
</div>
<div style={{ border: "10px solid red", padding: '20px', flex: 7 }} >
{/* <Routes> */}
{/* <Route path={"/about"} element={<About />} />
<Route path={"/home"} element={<Home />} />
<Route path={"/"} element={<Navigate to="/home" />} /> */}
{/* <Redirect to={"/home"} /> */}
{/* </Routes> */}
// 渲染路由表
{element}
</div>
</div>
</div >
)
}
useParams
接收 params 参数
路由表配置
import { useRoutes } from 'react-router-dom'
let element = useRoutes([
// params 参数
{
path: 'detail/:id/:title',
element: <Detail />,
}
])
Link配置
let v = { id: 0, title: '消息001' }
<Link to={`/home/message/detail/${v.id}/${v.title}` } >{v.title}</Link>
使用
import React from 'react'
import { useParams, useSearchParams, useLocation } from 'react-router-dom';
{/* params 参数 */}
export default function Detail(props) {
console.log('props', props);
let {title,id} = useParams()
return (
<div>
<ul>
<h1>ID:{id}</h1>
<h1>title:{title}</h1>
</ul>
</div>
)
}
useSearchParams
路由表配置
import { useRoutes } from 'react-router-dom'
let element = useRoutes([
// params 参数
{
path: 'detail',
element: <Detail />,
}
])
Link配置
let v = { id: 0, title: '消息001' }
<Link to={`/home/message/detail?id=${v.id} & title=${v.title}` } >{v.title}</Link>
使用
import { useSearchParams } from 'react-router-dom';
{/* search 参数 */}
export default function Detail() {
let [search, setSearch] = useSearchParams()
let id = search.get("id")
let title = search.get("title")
return (
<div>
<ul>
<h1>ID:{id}</h1>
<h1>title:{title}</h1>
</ul>
</div>
)
}
useLocation
路由表配置
import { useRoutes } from 'react-router-dom'
let element = useRoutes([
// params 参数
{
path: 'detail',
element: <Detail />,
}
])
Link配置
let v = { id: 0, title: '消息001' }
<Link to={`/home/message/detail`}
state={{ id: v.id, title: v.title }}
>{v.title}</Link>
使用
import { useSearchParams, useLocation } from 'react-router-dom';
{/* search 参数 */}
export default function Detail() {
let search = useLocation().state
let id = search.get("id")
let title = search.get("title")
return (
<div>
<ul>
<h1>ID:{id}</h1>
<h1>title:{title}</h1>
</ul>
</div>
)
}
useNavigate
编程时路由导航 => 只支持 state
import { useNavigate } from 'react-router-dom'
export default function Message() {
let navigate = useNavigate()
let mess = [{
id: 0,
title: '消息1'
},
{
id: 1,
title: '消息2'
},
{
id: 2,
title: '消息3'
}]
const seeDetail = (v) => {
navigate('detail', {
replace: false,
state: {
id: v.id,
title: v.title,
}
})
}
return (
<div>
<ul>
{
mess.map((v, i) => {
return <h1 key={i}><Link to={`/home/message/detail`} state={{ id: v.id, title: v.title }}
>{v.title}</Link>
<button onClick={() => seeDetail(v)} >查看详情</button>
</h1>
})
}
</ul>
<div>
<Outlet />
</div>
</div>
)
}
9.react-router5 和 react-router6 区别
1.内置组件的变化: 移除
2.语法的变化: component=(About}变为 element=(}等。
3.新增多个hook: useParams、useMatch等useNavigate
4.官方明确推荐函数式组件了!! !