每天学点React - 编程式路由导航

310 阅读2分钟

编程式路由导航

编程式路由导航,即通过js的方式来实现路由的跳转。在React中,我们可以通过propshistory属性来实现路由的跳转。

相关的属性有:

  • go
  • goBack
  • goForward
  • push
  • replace image.png

基础用法

go

前进/后退至第n个浏览页

this.props.history.go(n)

goBack

返回上一浏览页面

this.props.history.goBack()

goForward

返回下一浏览页面

this.props.history.goForward()

push

  1. push + params 模式
this.props.history.push(`/path/${参数1}/${参数2}`)
  1. push + search 模式
this.props.history.push(`/path/?属性1=${参数1}&属性2=${参数2}`)
  1. push + state 模式
this.props.history.push(`/path`, { 参数1, 参数2 })

replace

  1. replace + params 模式
this.props.history.replace(`/path/${参数1}/${参数2}`)
  1. replace + search 模式
this.props.history.replace(`/path/?属性1=${参数1}&属性2=${参数2}`)
  1. replace + state 模式
this.props.history.replace(`/path`, { 参数1, 参数2 })

在上面的属性中,pushreplace这两个都分别有三种模式,不同模式对应有不同的传参方式

  1. params方式传参

该方式需要我们在路径中传入对应的参数

<Link to={`/path/${参数1}/${参数2}`}>content</Link>

2.search方式传参 该方式无需修改路径,已将参数拼接在链接中

<Link to={`/path/`}>content</Link>
  1. state方式传参 该方式需要我们在标签to属性中定义state,用来传递相关的键值对
<Link to={{ pathname: "/path", state: { 属性1: 参数1, 属性2: 参数2 } }}>content</Link>

案例代码

「传参的路由组件」

import React, { Component } from 'react'
import {Link, Route} from 'react-router-dom'

import Detail from './Detail'

export default class D extends Component {

  state = {
    messageArr: [
      { id: '1', title: 'd_1' },
      { id: '2', title: 'd_2' },
      { id: '3', title: 'd_3' },
    ]
  }

  pushShow = (id, title) => {
    // 采用 push + params 模式跳转到下级路由组件
    // this.props.history.push(`/b/d/detail/${id}/${title}`)

    // 采用 push + search 模式跳转到下级路由组件
    // this.props.history.push(`/b/d/detail/?id=${id}&title=${title}`)

    // 采用 push + state 模式跳转到下级路由组件
    this.props.history.push(`/b/d/detail`, {id, title})
  }

  replaceShow = (id, title) => {
    // 采用 replace + params 模式跳转到下级路由组件
    // this.props.history.replace(`/b/d/detail/${id}/${title}`)

    // 采用 replace + search 模式跳转到下级路由组件
    // this.props.history.replace(`/b/d/detail/?id=${id}&title=${title}`)

    // 采用 replace + state 模式跳转到下级路由组件
    this.props.history.replace(`/b/d/detail`, {id, title})
  }

  render() {
    const { messageArr } = this.state
    return (
      <div>
        <ul>
          {
            messageArr.map((message) => {
              return (
                <li key={message.id}>
                  {/* params方式传参 */}
                  {/* <Link to={`/b/d/detail/${message.id}/${message.title}`}>{message.title}</Link> */}

                  {/* search方式传参 */}
                  {/* <Link to={`/b/d/detail/`}>{message.title}</Link> */}

                  {/* state方式传参 */}
                  <Link to={{pathname: "/b/d/detail", state: {id: message.id, title: message.title}}}>{message.title}</Link>

                  &nbsp;<button onClick={() => this.pushShow(message.id, message.title)}>push查看</button>
                  &nbsp;<button onClick={() => this.replaceShow(message.id, message.title)}>replace查看</button>
                </li>
              )
            })
          }
        </ul>
        <hr/>
        {/* 申明接收params参数 */}
        {/* <Route path='/b/d/detail/:id/:title' component={Detail}></Route> */}

        {/* search、state 参数无需声明接收 */}
        <Route path='/b/d/detail' component={Detail}></Route>
      </div>
    )
  }
}

「接收的路由组件」

import React, { Component } from 'react'

// import qs from 'querystring-es3'


const detailDate = [
  { id: '1', content: 'd_1展示区' },
  { id: '2', content: 'd_2展示区' },
  { id: '3', content: 'd_3展示区' },
]

export default class Detail extends Component {

  render() {
    console.log(this.props)

    // 接收params参数
    // const {match:{params:{id, title}}} = this.props

    // 接收search参数
    // const {search} = this.props.location || {}
    // const {id, title} = qs.parse(search.slice(1))

    // 接收state参数
    const { id, title } = this.props.location.state || {}

    const findData = detailDate.find(detail => detail.id === id) || {}
    return (
      <div>
        {title + ': ' + findData.content}
      </div>
    )
  }
}

push与replace效果展示

image.png

image.png

image.png

image.png

本文正在参加「金石计划 . 瓜分6万现金大奖」