react路由

react路由分三种,这里主要介绍 react-rotuer-dom

  • BrowserRouter:最大的容器,全局只能有一个,route所有的配置都要放在里面才会有效果 Browser(有浏览器的意思) 所以一般直接包裹app.js的根元素。

    • forceRefresh:控制react-router跳转的时候刷新页面或不刷新页面,值为boolean
      使用:
  • HashRouter:与BrowserRouter作用相同,不同是以hash的方式进行跳转。

  • Link : 进行跳转

  • Route : 进行匹配

  • NavLink:Link的升级版,自带”active“ class名

    • 属性:activeClassName: 修改高亮的class名
  • Switch:提高效率,优化匹配机制,检测到相同的path之后,不会继续向下传递
    为什么使用Switch?
    重复的path会让两个组件同时显示,所以由两个或两个以上的Route,就需要使用Switch包裹

  • Redirect:一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由

  • withRouter:让一般组件实现路由跳转

  • Prompt: React 阻止路由离开(路由拦截)

    <Prompt
    	when={true}
    	message={location => '信息还没保存,确定离开吗?'}
    

/>
```

一般组件与路由组件

  • 写法不同:
    一般组件:
    路由组件:
  • 接收到props不同
    一般组件:写组件标签时传递的什么,就能收到什么
    路由组件:接收到三个固定的属性
    • history:
      • go
      • goBack
      • goForward
      • push:fn(path,state)
      • replace:fn(path,state)
    • localtion:
      • pathname
      • search
      • state:undefined
    • match:
      • params:{}
      • path:"/about"
      • url:"/about"

精准匹配&模糊匹配

  • 模糊匹配(默认):【输入的路径】必须包含要【匹配的路径】,且顺序要一致
    添加属性replace={true},开启replace模式
  • 精准匹配:Route中添加exact属性
    【注意】严格匹配不要随便开启,需要再开,有些时候开启会导致无法继续匹配二级路由
    值为Boolean ,默认为true

路由传参的三种方式

  • 向路由组件传递params参数

路由链接(传递参数)

注册路由(声明接收)

子组件通过 props.match.params 接收参数

  • 传递search参数

路由链接(会将属性和值一块传递)

注册路由(正常写即可)

子组件通过 props.localtion.serach 可以拿到“?id=1&title=‘标题1’” urlencoded编码字符串
通过简单处理就可以使用
react有自带的方法
import qs from 'querystring
有stringify 和jsonparse 两个方法(和JSON的方法一样)

  • state参数(隐式传参,与组件状态的state无关,不同于vue的隐式传参,刷新可以保留参数)

优点:传递的参数在地址栏中是不显示的
路由链接(对象的方式传递,两个属性pathname和state)

注册路由(正常写即可)

子组件通过 props.localtion.state 接收参数

编码方式(传参形式)?????

urlencoded JSON query params

一般组件实现路由跳转(withRouter)

withRouter可以加工一般组件,让一般组件具备组件所特有的API
withRouter返回值是一个新组建(包含路由组件的API)
import {withRouter} from 'react-router-dom'
导出组件时导出的时withRouter(Header)函数的返回值

BrowserRouter与HashRouter的区别?

1、底层原理不一样:

  • BrowserRouter使用的是H5的history的API,不兼容IE9及以下的版本。
  • HashRouter使用的是URL的哈希值

2、path的表现形式不一样

  • BrowserRouter的路径没有#,例如:localhost:3000/demo/test
  • HashRouter的路径包含#,例如:localhost:3000/#/demo/test

3、刷新后对路由state参数的影响

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

4、【备注】:HashRouter可以用于解决一些路径错误相关的问题

这里来一个小例子

场景:常见的列表中获取某一条数据的详情。
三个组件:

  • index.jsx :根组件
  • List.jsx:列表组件
  • Detail.jsx:详情组件
//index
import React, { Component } from 'react';
import { NavLink, Route, Switch, Redirect } from 'react-router-dom'

import List from './List';
import Detail from './Detail';
class View extends Component {

  state = {
    list:[]
  }

  render() {
    return (
      <React.Fragment>
        <NavLink to="/list"/>
        <Switch>
          <Route path="/list" component={List}></Route>
          <Route path="/Detail/:type" component={Detail}></Route>
          <Redirect to="/list" />
        </Switch>
      </React.Fragment>
    );
  }
}

export default View;

//List组件
import React, { Component } from 'react'
import axios from '../../unit'
export class List extends Component {

  state = {
    list:[]
  }

  componentDidMount() {
    // 请求数据
     axios('get', '/home/mediareports?', { page_number: 1, page_size: 20 }).then(res => {
      this.setState({ list: res.data.data })
    })
  }

  // 动态传参
  onTarget(id) {
    this.props.history.push(`/detail/${id}`)
  }

  // 渲染页面
  rList() {
    return this.state.list.map(item => (
      <li key={item.id} onClick={()=>{this.onTarget(item.id)}}>
        <p>{ item.main_title }</p>
      </li>
    ))
  }

  render() {
    return (
      <ul>
        {this.rList()}
      </ul>
    )
  }
}

export default List

//Detail组件
import React, { Component } from 'react'
import axios from '../../unit'
export class Detail extends Component {
  
  state = {
    obj:{}
  }

  componentDidMount() {
    // 获取数据
    axios('get', '/home/mediareports?', { page_number: 1, page_size: 20 }).then(res => {
      const data = res.data.data;
      // 拿到params参数
      const id = this.props.match.params.type;
      // 这一块没有获取单个数据接口,所以需要筛选一下
      const obj = data.filter(item => item.id === id)[0]
      this.setState({obj})
    })
  }

  render() {
    let { obj } = this.state
    console.log(obj)
    return (
      <ul>
        <li>标题:{ obj.main_title }</li>
        <li>来源:{ obj.source }</li>
        <li>时间:{ obj.sourceDate }</li>
      </ul>
    )
  }
}

export default Detail

lazy的使用

  • 引入:import React,{ lazy, Suspense } from 'react';
  • 使用:
    const About = lazy(() => import('地址'))
//必须用Suspense 包裹,默认有一个loading回调
<Suspense fallback={<div>loading...</div>}>
  <Route exact path="/" component={Home} />
  <Route path="/about" component={About} />
  <Redirect to="/" />
</Suspense>

你可能感兴趣的:(react)