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={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参数:

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

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

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

search参数:

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

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

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

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

state参数:

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

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

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

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

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

  • 48
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 78
    评论
React Hooks是一种React的函数式编程方式,用于在函数组件中使用React的功能。在React中,有多种方式可以实现路由传参,其中包括params、query、state和使用React Router提供的hooks。 1. 使用params方式进行路由传参params方式是通过在路由路径中定义参数来传递数据。可以在路由配置中定义参数,并通过路由组件props或者useParams hook来获取传递的参数值。这种方式的优点是直观、简洁,适合传递较少的数据。但是缺点是参数是直接暴露在URL中,可能会导致安全性问题和浏览器历史记录的混乱。 2. 使用query方式进行路由传参:query方式是通过在URL的查询字符串中传递数据。可以使用React Router提供的useLocation hook来获取查询字符串并解析参数。这种方式的优点是可以传递任意数量的参数,并且参数值可以是任意类型。但是缺点是URL会变得较长,不够直观,且需要手动解析参数。 3. 使用state方式进行路由传参state方式是通过将参数保存在组件状态中进行传递。可以使用React Router提供的useLocation hook来获取传递的参数值。这种方式的优点是可以传递复杂的数据结构,并且参数值不会暴露在URL中。但是缺点是参数值只在页面刷新后会丢失。 4. 使用React Router提供的hooks进行路由传参React Router还提供了一些hooks,如useParams、useLocation和useMatch等,可以方便地获取路由参数。useParams用于获取params方式传递的参数,useLocation用于获取query方式传递的参数,useMatch用于获取匹配当前URL的路由信息。 根据具体需求和场景,选择合适的方式进行路由传参。如果传递的数据较少且不涉及敏感信息,可以使用params方式;如果传递的参数较多或需要保护敏感信息,可以使用query方式state方式;如果需要方便地获取路由参数,可以使用React Router提供的hooks。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [react及hook路由传参](https://blog.csdn.net/weixin_46449470/article/details/120370287)[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: 50%"] - *2* *3* [ReactRouter6路由传值hooks](https://blog.csdn.net/phaple/article/details/128734513)[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: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 78
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

蜡笔雏田学前端

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

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

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

打赏作者

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

抵扣说明:

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

余额充值