react——路由(V5)

React路由

React Router 是完整的 React 路由解决方案

React Router 保持 UI 与 URL 同步。它拥有简单的 API 与强大的功能例如代码缓冲加载、动态路由匹配、以及建立正确的位置过渡处理。你第一个念头想到的应该是 URL,而不是事后再想起。

路由得基本使用

  1. 明确好界面中的导航区、展示区
  2. 导航区的a标签改为Link标签:**Demo**
  3. 展示区写Route标签进行路径的匹配
  4. 的最外侧包裹了一个

路由组件和一般组件

  1. 写法不同

    1
    2
    3
    4
    //一般组件
    <Demo/>
    // 路由组件
    <Route path="/demo" component={Demo}/>
  2. 存放位置不同

  • 一般组件:components
  • 路由组件:pages
  1. 接收到的props不同
  • 一般组件:写组件标签时传递了什么,就能收到什么

  • 路由组件:接收三个固定的属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    history:
    go:f go(n)
    goBack:f goBack()
    goFward:f goFoward()
    push:f push(path,state)
    replace:f replace(path,state)
    location:
    pathname:"/about"
    search:""
    state:undefined
    match:
    params:{}
    path:"/about"
    url:"/about"
  • 动态给路由标签添加属性,默认是active,NavLink可以实现路由链接的高亮,通过activeClassName指定样式名字

    1
    <NavLink activeClassName="active" className="list-group-item" to="/about">About</NavLink>
  • 标签体内容是一个特殊的标签属性

  • 通过 this.props.children可以获取标签体内容

Switch

  • 通常情况下,path和component是一一对应的关系,Switch可以提高路由匹配率(单一匹配)

  • 在注册路由的时候,将Route使用Switch包裹起来,路由从上至下匹配到第一个就不会继续向下匹配了

    1
    2
    3
    4
    5
    6
    <Switch>
    <Route path="/about" component={About}/>
    <Route path="/home" component={Home}/>
    {/*Test组件不会展示*/}
    <Route path="/home" component={Test}/>
    </Switch>

解决多级路径刷新页面央视丢失的问题

  1. public/index.html 中引入样式时不写 .// (常用)
  2. public/index.html 中引入样式时不写 ./ 写%PUBBLIC_URL%(常用)
  3. 使用HashRouter

路由的严格匹配与模糊匹配

  1. 默认使用的时模糊匹配:输入的路径必须包含要匹配的路径,且顺序要一致
  2. 开启严格匹配:
  3. 严格匹配不要随便开启,需要再开,有时候会导致无法继续匹配二级路由

Redirect的使用

  1. 一般写在所有路由的最下方,当所有路由都无法匹配的时候,跳转到Redirect指定的路由

  2. 具体编码

    1
    2
    3
    4
    5
    <Switch>
    <Route path="/sola/about" component={About}/>
    <Route path="/sola/home" component={Home}/>
    <Redirect to="/sola/about" />
    </Switch>

嵌套路由

  1. 注册子路由时要写上父路由的path值
  2. 路由的匹配是按照路由的注册顺序进行的

向路由组件传递参数

1.params参数

  1. 路由链接(携带参数)

    1
    <Link to={`/home/message/detail/${messageObj.id}/${messageObj.title}`}>{messageObj.title}</Link>
  2. 注册路由(声明接收)

    1
    <Route   path="/home/message/detail/:id/:title" component={Detail} />
  3. 接收参数

    1
    const {id,title} = this.props.match.params

2.search参数

  1. 路由链接(携带参数)

    1
    <Link to={`/home/message/detail/?id=${messageObj.id}&title=${messageObj.title}`}>{messageObj.title}</Link>
  2. 注册路由(无需声明、正常注册即可)

    1
    <Route   path="/home/message/detail" component={Detail} />
  3. 接收参数

    1
    2
    3
    4
    import qs from 'querystring'
    // 接收search参数
    const {search} = this.props.location
    const {id,title} = qs.parse(search.slice(1))
  4. 备注:获取到的search是urlencoded编码字符串,需要借助querystring解析

3.state参数

  1. 路由链接(携带参数)

    1
    2
    3
    4
    <Link to={{
    pathname: '/home/message/detail',
    state: {id: messageObj.id, title: messageObj.title}
    }}>{messageObj.title}</Link>
  2. 注册路由(无需声明、正常注册即可)

    1
    <Route   path="/home/message/detail" component={Detail} />
  3. 接收参数

    1
    const {id,title} = this.props.location.state || {}
  4. 备注:刷新也可以保留住参数

编程式路由导航

  • 借助this.props.history对象上的API,对路由进行跳转、前进、后退
  • this.props.history.push()
  • this.props.history.replace()
  • this.props.history.goBack()
  • this.props.history.goFoward()
  • this.props.history.go()

withRouter

  • 可以加工一般组件,让一般组件具备路由组件所特有的API,返回值是一个新组件

    1
    2
    3
    import {withRouter} from 'react-router-dom'

    export default withRouter(Header);

BrowserRouter与HashRouter

1.底层原理不一样

  • BrowserRouter使用的是h5的history API,不兼容IE9以下版本
  • HashRouter使用的是url的哈希值

2.path表现形式不一样

  • BrowserRouter的路径中没有#
  • HashRouter‘的路径包含#

3.刷新后对路由state的影响:

  • BrowserRouter没有任何影响,因为state保存在history中
  • HashRouter刷新后会导致路由state参数的丢失

4.注意:HashRouter可以用于解决一些路径错误相关的问题