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

目录
  • 向路由组件传递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路由组件传参内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

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

    目录 向路由组件传递params参数 向路由组件传递search参数 向路由组件传递state参数 总结三种向路由组件传参的方式 向路由组件传递params参数 当点击消息1这个导航链接时,展示下方对应的Detail路由组件,并向这个组件传递params参数(ID,TITLE,CONTENT)信息. 向路由组件传递params参数:在路径后面跟上想要传递的值 { messageArr.map((msgObj) => { return ( <li key={msgObj.id}> <

  • 详解Vue 路由组件传参的 8 种方式

    我们在开发单页面应用时,有时需要进入某个路由后基于参数从服务器获取数据,那么我们首先要获取路由传递过来的参数,从而完成服务器请求,所以,我们需要了解路由传参的几种方式,以下方式同 vue-router@4 . 编程式路由传参 除了使用 <router-link> 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现. 1. 通过 params 传递 路由配置 路径参数 用冒号 : 表示. const routes = [ // 动态段以冒号开始 { pat

  • C#实现向多线程传参的三种方式实例分析

    本文实例讲述了C#实现向多线程传参的三种方式.分享给大家供大家参考,具体如下: 从<C#高级编程>了解到给线程传递参数有两种方式,一种方式是使用带ParameterizedThreadStart委托参数的Thread构造函数,另一种方式是创建一个自定义类,把线程的方法定义为实例的方法,这样就可以初始化实例的数据,之后启动线程. 方式一:使用ParameterizedThreadStart委托 如果使用了ParameterizedThreadStart委托,线程的入口必须有一个object类型的

  • 浅谈react路由传参的几种方式

    第一种传参方式,动态路由传参 通过设置link的path属性,进行路由的传参,当点击link标签的时候,会在上方的url地址中显示传递的整个url <Link to='/home?name=dx'>首页</Link> 如果想真正获取到传递过来的参数,需要在对应的子组件中 this.props.location.search 获取字符串,再手动解析 因为传参能够被用户看见,传递获取比较麻烦,所以不推荐 第二种传参方式,隐式路由传参 <Link to={{ pathname: '

  • 详解Vue路由传参的两种方式query和params

    Vue路由传参的两种方式query和params 一.router-link 1. 不带参数 <router-link :to="{name:'home'}"> <router-link :to="{path:'/home'}"> //name,path都行, 建议用name // 注意:router-link中链接如果是'/'开始就是从根路由开始,如果开始不带'/',则从当前路由开始. 2.带参数 <router-link :to=&

  • angular1.x ui-route传参的三种写法小结

    如下所示: .state('classrooms',{ url: '/classrooms/:id' }) .state('classrooms',{ url: '/classrooms/{id}' }) .state('activities',{ url: '/activities', params: { id: { value: 42} } }) localhost:3000/#/classrooms/3 function ClassroomController($stateParams){

  • vue-router传参的4种方式超详细讲解

    目录 一.router-link路由导航方式传参 二.调用$router.push实现路由传参 三.通过路由属性name匹配路由,再根据params传递参数 四.通过query来传递参数 总结 一.router-link路由导航方式传参 父组件:<router-link to="/跳转到的路径/传入的参数"></router-link> 子组件:this.$route.params.content接受父组件传递过来的参数 例如: 路由配置: bashbash{p

  • vue-router传参的四种方式超详细讲解

    目录 vue路由传参的四种方式 一.router-link路由导航方式传参 二.调用$router.push实现路由传参 三.通过路由属性name匹配路由,再根据params传递参数 四.通过query来传递参数 vue-router传递参数的几种方式 vue路由传参的四种方式 一.router-link路由导航方式传参 父组件:<router-link to="/跳转到的路径/传入的参数"></router-link>子组件:this.$route.param

  • 详解vue-router传参的两种方式

    Vue Router 是 Vue.js 官方的路由管理器.它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌.包含的功能有: 嵌套的路由/视图表 模块化的.基于组件的路由配置 路由参数.查询.通配符 基于 Vue.js 过渡系统的视图过渡效果 细粒度的导航控制 带有自动激活的 CSS class 的链接 HTML5 历史模式或 hash 模式,在 IE9 中自动降级 自定义的滚动条行为 vue-router传参两种方式:params和query params.query是什么? p

  • 小程序页面间传参的五种方式实例详解

    目录 前言 1.使用globalData 2.使用storage 3.使用url 3.1 api跳转 3.2 组件跳转 4.使用通信通道 5.使用页面栈 总结 前言 由于经常需要进行页面间传参且各种传参的业务场景也不相同,根据官方文档和日常工作进行了总结.共有五种传参方式,各位有什么关于页面间传参的奇思妙想也可在评论区提出,大家共同探讨 概览: 方式 优点 缺点 globalData 双向传参.全应用可用 不及时 storage 双向传参.全应用可用 不及时 路由 简单方便.及时 正向传参 通信

随机推荐