react-router-dom
yarn add react-router-dom@5
Link
标签包裹<Link to="/home">Home</Link>
Route
标签进行匹配<Route path='/home' component={Home} />
<App/>
最外侧包裹一个<BrowserRouter>
或者<HashRouter>
<Demo/>
<Route path='/home' component={Home} />
components
文件夹pages
文件夹中,props
不同:
history:
go: ? go(n)
goBack: ? goBack()
goForward: ? goForward()
push: ? push(path, state)
replace: ? replace(path, state)
location:
pathname: "/home"
search: ""
state: undefined
match:
params: {}
path: "/home"
url: "/home"
NavLink
与封装NavLink
NavLink
可以实现路由链接的高亮,通过activeClassName
指定样式名this.props.children
可以获取标签体内容使用NavLink
封装NavLink
Switch
的使用path
和component
是一一对应的关系Switch
可以提高路由匹配效率(单一匹配)publick/index.html
中,引入样式时不写./
写/
(常用)publick/index.html
中,引入样式时不写./
写%PUBLIC_URL%
(常用)HashRouter
publick/index.html
返回exact
<Route exact path='/about' component={About}/>
Redirect
的使用<Switch>
<Route path='/home' component={Home} />
<Route path='/about' component={About} />
{/* 写在最底部,重定向, 路由都匹配不上,就去 to ... */}
<Redirect to='/home'/>
</Switch>
path
值params
参数<Link to={`/about/message/detail/${item.id}/${item.title}`}>{item.title}</Link>
<Route path='/about/message/detail/:id/:title' component={Detail}/>
const {id, title} = this.props.match.params
search
参数<Link to={`/about/message/detail?id=${item.id}&title=${item.title}`}>{item.title}</Link>
<Route path='/about/message/detail' component={Detail}/>
// search 接收参数 react自动安装的库
import qs from 'querystring'
const {search} = this.props.location
const {id, title} = qs.parse(search.slice(1))
search
是urlencoded
编码,需要借助querystring
解析<Link to={{pathname:'/about/message/detail', state:{
id: item.id,
title: item.title
}}}>{item.title}</Link>
// state参数无需声明接收,正常注册路由即可
<Route path='/about/message/detail' component={Detail}/>
const {id, title} = this.props.match.state
push
与replace
replace
属性,将不会再进行压栈,浏览器不会有回退记录<MyNavLink replace to='/about/message'>Message</MyNavLink>
借助this.props.history
对象上的API
对操作路由跳转、前进、后退
this.props.history.push()
this.props.history.replace()
this.props.history.goBack()
this.props.history.goForward()
this.props.history.go()
withRouter
withRouter
可以加工一般组件,让一般组件具备路由组件所持有的API
withRouter
的返回值是一个新组件import { withRouter } from 'react-router-dom'
export default withRouter(Hearder)
示例中:普通组件想要实现路由跳转
App.js
中:
BrowserRouter
和HashRouter
的区别BrowserRouter
使用的使H5
的history
的API
,不兼容IE9
及以下版本,HashRouter
使用的使URL
的哈希值BrowserRouter
的路径中间没有#,例如:localhost:3000/demo/test
HashRouter
的路径包含#,例如:localhost:3000/#/demo/test
state
参数的影响BrowserRouter
没有影响,因为state
保存在history
对象中HashRouter
刷新后会导致路由state
参数丢失HashRouter
可以用于解决一些路径错误相关的问题react Router
三个不同的包发布在npm
上:它们分别是:
react-router
: 路由的核心库,提供很多的:组件,钩子react-router-dom
: 包含react-router
所以内容,并添加一些专门用于DOM
组件。例如<BrowerRouter>
等react-router-native
: 包含react-router
所以内容,并添加一些专门用于ReactNative
的API
。例如<NativeRouter>
等React Router 5.x
版本相比,改变了什么?
<Switch/>
,新增<Routes/>
等component={About}
变为elemet={<About/>}
等hook
:useParams
、useNavigate
、useMatch
等Component
<BerwserRouter>
<HashRouter>
<Routes/>和<Route/>
v6
版本中移除了<Switch>
,引入了新的替代者:<Routes>
<Routes>
和<Route>
要配合使用,且必须要用<Routes>
包裹<Route>
<Route>
相当于一个if
语句,如果其路径与当前URL
匹配,则呈现其对应的组件<Route caseSensitive>
属性用于指定:匹配时是否区分大小写(默认为fasle
)URL
发生变化时,<Routes>
都会查看其所有子<Route>
元素以找到最佳匹配并呈现组件<Route>
也可以嵌套使用,且配合useRoutes()
配置"路由表",但需要通过<Outlet>
组件来渲染其子路由(见<Outlet/>
说明) // 路由表
const element = useRoutes({
path: '/home',
element: <Home/>
},
{
path: '/about',
element: <About/>,
children: [
{
path: 'news',
element: <News/>,
},
{
path: 'message',
element: <Message/>,
children: [
{
path: 'detail',
element: <Detail/>
}
]
}
]
},
{
path: '/',
element: <Navigate to='/about'/>
}
])
return (
<>
{/* 1. 在react中靠路由实现切换组件--编写路由链接 */}
<NavLink className={okTive} to='/home'>Home</NavLink>
<br/>
<NavLink className={okTive} to='/about'>About</NavLink>
{/* 2. 注册路由 */}
<hr/>
{/* Routes注册*/}
{/* <Routes>
<Route path='/home' element={<Home/>} />
<Route path='/About' element={<About/>} />
<Route path='/' element={<Navigate to="/about"/>}/>
</Routes> */}
{/* 路由表注册*/}
{element}
</>
)
<Link>
URL
,且不发送网络请求(路由链接)<BrowserRouter/>
和<HashRouter/>
包裹<NavLink>
<Link>
组件类似,且可实现导航的高亮效果<Navigate>
<Navigate>
组件被渲染,就会修改路径,切换视图replace
属性用于控制跳转模式,(push
或replace
,默认是push
)import {useState} from 'react'
import {Navigate} from 'react-router-dom'
export default function Home() {
const [num, setNum] = useState(1)
return (
<>
{num === 2
? <Navigate to='/about' replace/>
: <h4>num的值是{num}</h4>}
<button onClick={() => setNum(2)}>点击</button>
</>
)
}
<Outlet>
<Route>
产生嵌套是,渲染其对应的后续子路由<div>
<ul>
<li>
{/* <NavLink className={okTive} to='news'>News</NavLink> */}
{/* <NavLink className={okTive} to='/about/news'>News</NavLink> */}
<NavLink className={okTive} to='./news'>News</NavLink>
</li>
<li>
<NavLink className={okTive} to='message'>Message</NavLink>
</li>
</ul>
{/* 指定路由组件呈现的位置(二级+路由) */}
<Outlet/>
</div>
HOOKS
useRoutes()
<Routes>
和<Route>
useNavigate()
import { useNavigate } from 'react-router-dom'
export default function Hearder() {
const navigate = useNavigate()
const back = () => {
navigate(-1)
}
const forward = () => {
navigate(1)
}
const handleClick = () => {
navigate('detail',{
replace: false,
state: {
id: '122',
title: '小明',
content: '热爱祖国'
}
})
}
return (
<>
<button onClick={back}>后退</button>
<button onClick={forward}>前进</button>
<button onClick={handleClick}>跳转详情</button>
</>
)
}
useParams()
params
参数useSearchParams()
search
参数、更新search
的函数useLocation()
location
信息,对标5.x中的路由组件的localtion
属性(可用于获取state
参数)useMatch()
match
属性useInRouterContext()
(APP.jsx)<Router/>
的上下文中呈现(被路由包裹的组件),则useRouterContext
钩子返回true
,否则false
useNavigationType()
(News.jsx)POP
,PUSH
,REPLACE
POP
是指在浏览器中直接打开了这个路由组件(刷新页面)useOutlet()
(About.jsx)const a = useOutlet()
console.log(a, 'useOutlet嵌套')
// 如果嵌套路由没有挂载,则a为null
// 如果嵌套路由已经挂载,则展示嵌套路由对象
useResolvedPath()
(News.jsx)URL
值,解析其中的:path
、search
、hash
值