您当前的位置: 首页 >  ar

暂无认证

  • 6浏览

    0关注

    92582博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

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

发布时间:2022-07-14 09:27:59 ,浏览量:6

文章目录
  • 🔥向路由组件传递params参数
  • 🔥向路由组件传递search参数
  • 🔥向路由组件传递state参数
  • 🔥总结三种向路由组件传参的方式

今天来学习一下向路由组件传递参数的三种方式。 感兴趣的伙伴可以仔细看看~

在这里插入图片描述

🔥向路由组件传递params参数

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

在这里插入图片描述

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

{
  messageArr.map((msgObj) => {
    return (
      
			 
			 {msgObj.title}
      
    )
 })
}

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


这样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 (
      
        
          {
            messageArr.map((msgObj) => {
              return (
                
                  {/* 向路由组件传递params参数 */}
                  
                  {msgObj.title}
                
              )
            })
          }
        
        
        {/* 注册路由 */}
        {/* 声明接收params参数 */}
        
      
    )
  }
}

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 (
      
        ID: {id}
        TITLE: {title}
        CONTENT: {findResult.content}
      
    )
  }
}
🔥向路由组件传递search参数

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

在这里插入图片描述

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

{
  messageArr.map((msgObj) => {
    return (
      
				{/* 向路由组件传递search参数 */}
				
				{msgObj.title}
      
   )
 })
}

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


这样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 (
      
        
          {
            messageArr.map((msgObj) => {
              return (
                
                  {/* 向路由组件传递search参数 */}
                  
                  {msgObj.title}
                
              )
            })
          }
        
        
        {/* 注册路由 */}
        {/* search参数无需声明接收,正常注册路由即可 */}
        
      
    )
  }
}

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 (
      
        ID: {id}
        TITLE: {title}
        CONTENT: {findResult.content}
      
    )
  }
}
🔥向路由组件传递state参数

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

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

向路由组件传递state参数:

{
  messageArr.map((msgObj) => {
    return (
      
        {/* 向路由组件传递state参数 */}
		
		{msgObj.title}

)
})
}

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

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


这样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 (
      
        
          {
            messageArr.map((msgObj) => {
              return (
                
                  {/* 向路由组件传递state参数 */}
                  
                  {msgObj.title}
                
              )
            })
          }
        
        
        {/* 注册路由 */}
        {/* state参数无需声明接收,正常注册路由即可 */}
        
      
    )
  }
}

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 (
      
        ID: {id}
        TITLE: {title}
        CONTENT: {findResult.content}
      
    )
  }
}

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

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

const findResult = DetailData.find((detailObj) => {
  // 如果某一项对象的id和我传过来的Id相等,findResult就等于这一项对象
  return detailObj.id === id
}) || {}
🔥总结三种向路由组件传参的方式

params参数:

  1. 路由链接(携带参数):详情

  2. 注册路由(声明接收):

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

search参数:

  1. 路由链接(携带参数):详情

  2. 注册路由(无需声明,正常注册即可):

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

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

state参数:

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

  2. 注册路由(无需声明,正常注册即可):

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

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

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

关注
打赏
1653961664
查看更多评论
立即登录/注册

微信扫码登录

0.5301s