React路由组件传参的三种方式(params、search、state)

 更新时间:2022年07月21日 14:16:54   作者:蜡笔雏田学代码  
本文主要介绍了React路由组件传参的三种方式,主要包括了params、search、state,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

🔥向路由组件传递params参数

当点击消息1这个导航链接时,展示下方对应的Detail路由组件,并向这个组件传递params参数(ID,TITLE,CONTENT)信息。

在这里插入图片描述

向路由组件传递params参数:在路径后面跟上想要传递的值

{
  messageArr.map((msgObj) => {
    return (
      <li key={msgObj.id}>
			 <Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>
			 {msgObj.title}</Link>
      </li>
    )
 })
}

注册路由时,声明接收params参数

<Route path="/home/message/detail/:id/:title" component={Detail} />

这样id,title参数就传递给了Detail组件,Detail组件可以通过this.props.match.params拿到参数。

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

在这里插入图片描述

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' }
    ]
  }
  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>
                </li>
              )
            })
          }
        </ul>
        <hr />
        {/* 注册路由 */}
        {/* 声明接收params参数 */}
        <Route path="/home/message/detail/:id/:title" component={Detail} />
      </div>
    )
  }
}

Detail->index.jsx:

import React, { Component } from 'react'

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

🔥向路由组件传递search参数

当点击消息1这个导航链接时,展示下方对应的Detail路由组件,并向这个组件传递search参数(ID,TITLE,CONTENT)信息。

在这里插入图片描述

向路由组件传递search参数:和params的写法有所不同

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

注册路由时,search参数无需声明接收,正常注册路由即可,因为传递search参数的路径里有一个关键符存在

<Route path="/home/message/detail" component={Detail} />

这样id,title参数就传递给了Detail组件,Detail组件可以通过this.props.location.search拿到参数。

但是,接收到的参数是一个 urlencoded 格式的(例如 name=tom&age=18 就是urlencoded格式)

在这里插入图片描述

所以我们需要将 urlencoded格式 转换为一个 对象 的形式,需要借助一个query-string库

// 安装query-string库
npm i --save --include=dev query-string
// 引入query-string
import qs from 'query-string'

query-string库里有两个方法stringfy()parse()

// 将object转化为urlencoded
qs.stringify()

// 将urlencoded转化为object
qs.parse()
// 接收search参数
const { search } = this.props.location
const { id, title } = qs.parse(search.slice(1))

在这里插入图片描述

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' }
    ]
  }
  render() {
    const { messageArr } = this.state
    return (
      <div>
        <ul>
          {
            messageArr.map((msgObj) => {
              return (
                <li key={msgObj.id}>
                  {/* 向路由组件传递search参数 */}
                  <Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>
                  {msgObj.title}</Link>
                </li>
              )
            })
          }
        </ul>
        <hr />
        {/* 注册路由 */}
        {/* search参数无需声明接收,正常注册路由即可 */}
        <Route path="/home/message/detail" component={Detail} />
      </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() {
    // 接收search参数
    const { search } = this.props.location
    const { id, title } = qs.parse(search.slice(1))

    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>
    )
  }
}

🔥向路由组件传递state参数

前面学的两个参数给组件传递的信息会在地址栏中展示出来,例如:localhost:3000/home/message/detail/?id=01&title=消息1,这是传递search参数的地址。

但是,传递state参数不会在地址栏中显示出来

向路由组件传递state参数:

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

注:这里的to属性要写成一个对象的形式(传递params和search参数都是字符串形式),对象有两个属性分别是:pathname以及state,需要传递的参数就放在state中。

注册路由时,search参数无需声明接收,正常注册路由即可。

<Route path="/home/message/detail" component={<!--{cke_protected}{C}%3C!%2D%2D%20%2D%2D%3E-->Detail} />

这样id,title参数就传递给了Detail组件,Detail组件可以通过this.props.location.state拿到参数。

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

在这里插入图片描述

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' }
    ]
  }
  render() {
    const { messageArr } = this.state
    return (
      <div>
        <ul>
          {
            messageArr.map((msgObj) => {
              return (
                <li key={msgObj.id}>
                  {/* 向路由组件传递state参数 */}
                  <Link to={{ pathname: '/home/message/detail', state: { id: msgObj.id, title: msgObj.title } }}>
                  {msgObj.title}</Link>
                </li>
              )
            })
          }
        </ul>
        <hr />
        {/* 注册路由 */}
        {/* state参数无需声明接收,正常注册路由即可 */}
        <Route path="/home/message/detail" component={Detail} />
      </div>
    )
  }
}

Detail->index.jsx:

import React, { Component } from 'react'

const DetailData = [
  { id: '01', content: '你好,中国' },
  { id: '02', content: '你好,程序员' },
  { id: '03', content: '你好,csdn' }
]
export default class Detail extends Component {
  render() {
    // 接收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>
    )
  }
}

有一个问题:当刷新页面,页面内容不会改变,原因是history下保存着state数据,当清除浏览器缓存,重新打开页面,数据会丢失。改为如下代码,页面刷新不会报错。

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

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

🔥总结三种向路由组件传参的方式

params参数:

路由链接(携带参数):<Link to=“/demo/test/tom/18”>详情

注册路由(声明接收):<Route path=“/demo/test/:name/:age” component={Test}/>

接收参数: this.props.match.params

search参数:

路由链接(携带参数):<Link to=“/demo/test?name=tom&age=18”>详情

注册路由(无需声明,正常注册即可):<Route path=“/demo/test” component={Test}/>

接收参数: this.props.location.search

备注:获取到的search是urlencoded编码字符串,需要借助querystring解析。

state参数:

路由链接(携带参数):<Link to={{pathname:‘/demo/test’,state: {name: ‘tom’,age:18}}}>详情

注册路由(无需声明,正常注册即可):<Route path=“/demo/test” component={Test}/>

接收参数: this.props.location.state

备注:如果不用BrowserRouter,刷新保留不住参数,因为BrowserRouter的history里保留了参数信息。

到此这篇关于React路由组件传参的三种方式(params、search、state)的文章就介绍到这了,更多相关React路由组件传参内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • React 子组件向父组件传值的方法

    React 子组件向父组件传值的方法

    本篇文章主要介绍了React 子组件向父组件传值的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • 使用react-router4.0实现重定向和404功能的方法

    使用react-router4.0实现重定向和404功能的方法

    本篇文章主要介绍了使用react-router4.0实现重定向和404功能的方法,具有一定的参考价值,有兴趣的可以了解一下
    2017-08-08
  • react native 获取地理位置的方法示例

    react native 获取地理位置的方法示例

    这篇文章主要介绍了react native 获取地理位置的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • React组件通信的实现示例

    React组件通信的实现示例

    在React中,组件通信是一个重要的概念,它允许不同组件之间进行数据传递和交互,本文主要介绍了React组件通信的实现示例,感兴趣的可以了解一下
    2023-11-11
  • React实现类似淘宝tab居中切换效果的示例代码

    React实现类似淘宝tab居中切换效果的示例代码

    这篇文章主要介绍了React实现类似淘宝tab居中切换效果,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • React styled-components设置组件属性的方法

    React styled-components设置组件属性的方法

    这篇文章主要介绍了styled-components设置组件属性的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • React报错Element type is invalid解决案例

    React报错Element type is invalid解决案例

    这篇文章主要为大家介绍了React报错Element type is invalid解决案例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • 在React项目中实现一个简单的锚点目录定位

    在React项目中实现一个简单的锚点目录定位

    锚点目录定位功能在长页面和文档类网站中非常常见,它可以让用户快速定位到页面中的某个章节,本文讲给大家介绍一下React项目中如何实现一个简单的锚点目录定位,文中有详细的实现代码,需要的朋友可以参考下
    2023-09-09
  • react中的watch监视属性-useEffect介绍

    react中的watch监视属性-useEffect介绍

    这篇文章主要介绍了react中的watch监视属性-useEffect使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • 使用React MUI库实现用户列表分页功能

    使用React MUI库实现用户列表分页功能

    MUI是一款基于React的UI组件库,可以方便地构建美观的用户界面,使用MUI的DataTable组件和分页器组件可以轻松实现用户列表分页功能,这篇文章使用MUI库实现了用户列表分页功能,感兴趣的同学可以参考下文
    2023-05-05

最新评论