【React路由】编程式路由导航和withRouter的使用——push / replace

上篇文章学习了 React路由组件传参的三种方式
本篇文章学习学习 编程式路由导航及相关知识点,感兴趣的小伙伴可以来个三连哦~

在这里插入图片描述

🌷路由的push与replace

push模式是栈的常规模式,可以回到上一级,会留下痕迹

replace模式是替换模式,会替换掉栈顶的路由,回不到上一级,不会留下痕迹(无痕模式),适用于登录后,不需要重新回到登录页。

开启方法:

<Link replace={true} to={{ pathname: '/home/message/detail', state: { id: msgObj.id, title: msgObj.title } }}>
{msgObj.title}
</Link>

🌷编程式路由导航

编程式路由导航:通过JS路由对象的方式来实现页面跳转(push、replace、go)

声明式路由导航: < < <Link > > > < < <NavLink > > >实现路由的跳转


随着react-router,可以使用Link元素创建的原生处理反应路由器链接。

但是,我不想点击链接进行导航,我想通过点击按钮自动实现页面跳转。实现方法如下:

  • push跳转+携带params参数
this.props.history.push(`/home/message/detail/${id}/${title}`) 	
  • push跳转+携带search参数
this.props.history.push(`/home/message/detail?id=${id}&title=${title}`)
  • push跳转+携带state参数
this.props.history.push(`/home/message/detail`, { id: id, title: title })

  • replace跳转+携带params参数
this.props.history.replace(`/home/message/detail/${id}/${title}`)
  • replace跳转+携带search参数
this.props.history.replace(`/home/message/detail?id=${id}&title=${title}`)
  • replace跳转+携带state参数
this.props.history.replace(`/home/message/detail`, { id: id, title: title })
  • 前进
this.props.history.goForward()
  • 回退
this.props.history.goBack()
  • 前进或回退 ( go )
this.props.history.go(-2)  //回退到前2条的路由

🌸案例需求

点击push按钮实现页面跳转,会留下历史记录,可以回到上一级;点击replace按钮也可以实现页面跳转,但是不会留下历史记录,不可以回到上一级;点击回退按钮,返回上一个记录的路由;点击前进按钮,前进一个记录的路由。

效果:

在这里插入图片描述

Message->index.jsx:

import React, { Component } from 'react'
import { Link, Route } from 'react-router-dom'
import Detail from './Detail';

export default class Message extends Component {
  state = {
    messageArr: [
      { id: '01', title: '消息1' },
      { id: '02', title: '消息2' },
      { id: '03', title: '消息3' }
    ]
  }

  replaceShow = (id, title) => {
    // 编写一段代码,让其实现跳转到Detail组件,且为replace跳转 +携带params参数
    // this.props.history.replace(`/home/message/detail/${id}/${title}`)

    // replace跳转 +携带search参数
    // this.props.history.replace(`/home/message/detail?id=${id}&title=${title}`)

    // replace跳转 +携带state参数
    this.props.history.replace(`/home/message/detail`, { id: id, title: title })
  }

  pushShow = (id, title) => {
    // 编写一段代码,让其实现跳转到Detail组件,且为push跳转 +携带params参数
    // this.props.history.push(`/home/message/detail/${id}/${title}`)

    // push跳转 +携带search参数
    // this.props.history.push(`/home/message/detail?id=${id}&title=${title}`)

    // push跳转 +携带state参数
    this.props.history.push(`/home/message/detail`, { id: id, title: title })
  }

  back = () => {
    this.props.history.goBack()
  }

  forward = () => {
    this.props.history.goForward()

  }

  go = () => {
    this.props.history.go(-2)
  }

  render() {
    const { messageArr } = this.state
    return (
      <div>
        <ul>
          {
            messageArr.map((msgObj) => {
              return (
                <li key={msgObj.id}>
                  {/* 向路由组件传递params参数 */}
                  {/* <Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>
                  {msgObj.title}
                  </Link> */}

                  {/* 向路由组件传递search参数 */}
                  {/* <Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>
                  {msgObj.title}
                  </Link> */}

                  {/* 向路由组件传递state参数 */}
                  <Link to={{ pathname: '/home/message/detail', state: { id: msgObj.id, title: msgObj.title } }}>
                  {msgObj.title}
                  </Link>

                  &nbsp;<button onClick={() => { this.pushShow(msgObj.id, msgObj.title) }}>
                  push查看
                  </button>
                  &nbsp;<button onClick={() => { this.replaceShow(msgObj.id, msgObj.title) }}>
                  replace查看
                  </button>
                </li>
              )
            })
          }
        </ul>
        <hr />
        {/* 注册路由 */}
        {/* 声明接收params参数 */}
        {/* <Route path="/home/message/detail/:id/:title" component={Detail} /> */}

        {/* search参数无需声明接收,正常注册路由即可 */}
        {/* <Route path="/home/message/detail" component={Detail} /> */}

        {/* state参数无需声明接收,正常注册路由即可 */}
        <Route path="/home/message/detail" component={Detail} />

        <button onClick={this.back}>回退</button>&nbsp;
        <button onClick={this.forward}>前进</button>&nbsp;
        <button onClick={this.go}>go</button>

      </div>
    )
  }
}

Detail->index.jsx:

import React, { Component } from 'react'
// 引入query-string库
// import qs from 'query-string'

const DetailData = [
  { id: '01', content: '你好,中国' },
  { id: '02', content: '你好,程序员' },
  { id: '03', content: '你好,csdn' }
]
export default class Detail extends Component {
  render() {
    console.log(this.props)
    // 接收params参数
    // const { id, title } = this.props.match.params

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

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

    const findResult = DetailData.find((detailObj) => {
      // 如果某一项对象的id和我传过来的Id相等,findResult就等于这一项对象
      return detailObj.id === id
    }) || {}
    return (
      <ul>
        <li>ID: {id}</li>
        <li>TITLE: {title}</li>
        <li>CONTENT: {findResult.content}</li>
      </ul>
    )
  }
}

🌸总结

借助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的使用

由于路由组件的props中是有history属性的,而一般组件(非路由组件)是没有history属性。所以在一般组件中,是不能使用history属性身上的API的(push/replace/goBack等)。但是,WithRouter函数可以解决上述问题。

引入WithRouter:

import {withRouter} from 'react-router-dom'

WithRouter :是一个函数接收一个一般组件作为参数,返回一个新组件,在新组件里的props里会被注入路由对象 ,让一般组件具备路由组件所特有的API

使用WithRouter:

class Header extends Component {
  // withRouter(Header)后,就可以在一般组件内部使用 this.props.history 
}
export default withRouter(Header)
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'

class Header extends Component {

  back = () => {
    this.props.history.goBack()
  }
  
  forward = () => {
    this.props.history.goForward()
  }

  go = () => {
    this.props.history.go(-2)
  }

  render() {
    console.log(this.props)
    return (
      <div className="page-header">
        <h2>React Router Demo</h2>
        <button onClick={this.back}>回退</button>&nbsp;
        <button onClick={this.forward}>前进</button>&nbsp;
        <button onClick={this.go}>go</button>
      </div>
    )
  }
}
export default withRouter(Header)

这样一般组件里也能使用路由组件所特有的API。

在这里插入图片描述

🌷BrowserRouter与HashRouter的区别

底层原理不一样:

(1).BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。

(2).HashRouter使用的是URL的哈希值

path表现形式不一样:

(1).BrowserRouter的路径中没有#,例如:localhost:3000/demo/test

(2).HashRouter的路径包含#,例如:localhost:3000/#/demo/test

刷新后路由state参数的影响:

(1).BrowserRouter没有任何影响,因为state保存在history对象中。

(2).HashRouter刷新后会导致路由state参数的丢失

备注:HashRouter可以用于解决一些路径错误相关的问题(多级路径刷新页面样式丢失的问题)。

今天的分享就到这里啦 ✨
如果对你有帮助的话,还请👉🏻关注💖点赞🤞收藏⭐评论🔥哦
不定时回访哟🌹

  • 52
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 102
    评论
WithRouterReact Router提供的一个高阶组件,用于将路由信息传递给被包裹的组件。通过使用WithRouter,我们可以在不是路由组件的地方访问到路由信息,比如在函数组件中。 WithRouter使用是通过导入`withRouter`函数,并将需要传递路由信息的组件作为参数传递给`withRouter`函数,然后将返回的高阶组件包裹在组件中。这样,被包裹的组件就可以通过props获取到路由信息,比如`history`、`location`和`match`等。 通过使用WithRouter,我们可以在被包裹的组件中实现编程路由导航。我们可以使用`props.history.push(path)`进行页面跳转,其中`path`是要跳转的路由路径。同样地,我们也可以使用`props.history.replace(path)`进行页面跳转,但是使用`replace`方法会替换当前的路由历史记录,而不是添加新的历史记录。 此外,React Router还提供了声明路由导航,可以使用`Link`和`NavLink`组件来实现路由的跳转。`Link`组件用于生成一个包含指定路径的超链接,点击该超链接时会触发路由的跳转。而`NavLink`组件是`Link`的一个特殊版本,它可以根据当前路由是否与指定路径匹配来添加`active`类名,方便我们为当前激活的导航项添加样。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [【React路由编程路由导航和withRouter使用——push / replace](https://blog.csdn.net/xuxuii/article/details/125786195)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 102
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蜡笔雏田学前端

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值