react-router
单页面应用
单页面应用是使用一个 html 前提下,一次性加载 js , css 等资源,所有页面都在一个容器页面下,页面切换实质是组件的切换。
路由原理
请看https://www.cnblogs.com/renzhiwei2017/p/16051483.html
React的路由
History ,React-Router , React-Router-Dom 三者的关系如下图:
主要有两种模式:
BrowserRouter模式和HashRouter模式。
在react路由中,这两种模式分别由React-Router-dom 根据 history 提供的 createBrowserHistory 或者 createHashHistory 创建出不同的 history 对象。
import { createBrowserHistory as createHistory } from "history";
class BrowserRouter extends React.Component {
history = createHistory(this.props)
render() {
return <Router history={this.history} children={this.props.children} />;
}
}
React-Router 基本构成
-
history location match
-
路由组件
1) Router
开发者一般不会直接使用 Router ,而是使用 react-router-dom 中 BrowserRouter 或者 HashRouter。
2) Route
Route的工作主要就是一个: 匹配路由,路由匹配,渲染组件。Route 可以通过 RouterContext.Consumer 来获取上一级传递来的路由进行路由匹配。
四种Route编写格式:
- Component 形式
- render 形式
- children 形式
- renderProps 形式
function Index(){
const mes = { name:'alien',say:'let us learn React!' }
return <div>
<Meuns/>
<Switch>
<Route path='/router/component' component={RouteComponent} /> { /* Route Component形式 */ }
<Route path='/router/render' render={(props)=> <RouterRender { ...props } /> } {...mes} /> { /* Render形式 */ }
<Route path='/router/children' > { /* chilren形式 */ }
<RouterChildren {...mes} />
</Route>
<Route path="/router/renderProps" >
{ (props)=> <RouterRenderProps {...props} {...mes} /> } {/* renderProps形式 */}
</Route>
</Switch>
</div>
}
export default Index
exact
Route 可以加上 exact ,来进行精确匹配。如果是嵌套路由的父路由,千万不要加 exact=true 属性。
3)Switch
Switch 作用就是匹配唯一正确的路由并渲染。
<Switch>
<Route path='/home' component={Home} />
<Route path='/list' component={List} />
<Route path='/my' component={My} />
</Switch>
4) Redirect
Redirect 可以在路由不匹配情况下跳转指定某一路由,适合路由不匹配或权限路由的情况。
注意 Switch 包裹的 Redirect 要放在最下面,否则会被 Switch 优先渲染 Redirect ,导致路由页面无法展示。
路由使用指南
- 路由状态获取
- 通过props传递
- withRouter
对于嵌套深的组件推荐使用withRouter - useHistory 和 useLocation
import { useHistory ,useLocation } from 'react-router-dom'
function Home(){
const history = useHistory() /* 获取history信息 */
const useLocation = useLocation() /* 获取location信息 */
}
- 路由带参数跳转
2.1 路由跳转
- 声明式:
,利用 react-router-dom 里面的 Link 或者 NavLink 。 - 函数式:histor.push('/home')
2.2 参数传递
url拼接
const name = 'alien'
const mes = 'let us learn React!'
history.push(`/home?name=${name}&mes=${mes}`)
state路由状态
const name = 'alien'
const mes = 'let us learn React!'
history.push({
pathname:'/home',
state:{
name,
mes
}
})
2.3 动态路径参数路由
<Route path="/post/:id" />
history.push('/post/'+id) // id为动态的文章id
2.4 嵌套路由
/* 第二层嵌套路由 */
function Home(){
return <div>
<Route path='/home/test' component={Test} />
<Route path='/home/test1' component={Test1} />
</div>
}
/* 第一层父级路由 */
function Index(){
return <Switch>
<Route path="/home" component={Home} />
<Route path="/list" component={List} />
<Route path="/my" component={My} />
</Switch>
}
嵌套路由子路由一定要跟随父路由。比如父路由是 /home ,那么子路由的形式就是 /home/xxx ,否则路由页面将展示不出来。