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


文章目录

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

今天来学习一下向路由组件传递参数的三种方式。
感兴趣的伙伴可以仔细看看~
React|React路由组件传参的三种方式——params、search、state
文章图片

向路由组件传递params参数 当点击消息1这个导航链接时,展示下方对应的Detail路由组件,并向这个组件传递params参数(ID,TITLE,CONTENT)信息。
React|React路由组件传参的三种方式——params、search、state
文章图片

向路由组件传递params参数:在路径后面跟上想要传递的值
{ messageArr.map((msgObj) => { return (
  • {msgObj.title}
  • ) }) }

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

    这样id,title参数就传递给了Detail组件,Detail组件可以通过this.props.match.params拿到参数。
    // 接收params参数 const { id, title } = this.props.match.params

    React|React路由组件传参的三种方式——params、search、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 (
    • {/* 向路由组件传递params参数 */} {msgObj.title}
    • ) }) }
    {/* 注册路由 */} {/* 声明接收params参数 */}
    ) } }

    Detail->index.jsx:
    import React, { Component } from 'react'const DetailData = https://www.it610.com/article/[ { 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)信息。
    React|React路由组件传参的三种方式——params、search、state
    文章图片

    向路由组件传递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格式)
    React|React路由组件传参的三种方式——params、search、state
    文章图片

    所以我们需要将 urlencoded格式 转换为一个 对象 的形式,需要借助一个query-string库。
    // 安装query-string库 npm i --save --include=dev query-string // 引入query-string import qs from 'query-string'

    【React|React路由组件传参的三种方式——params、search、state】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))

    React|React路由组件传参的三种方式——params、search、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 (
    • {/* 向路由组件传递search参数 */} {msgObj.title}
    • ) }) }
    {/* 注册路由 */} {/* search参数无需声明接收,正常注册路由即可 */}
    ) } }

    Detail->index.jsx:
    import React, { Component } from 'react' // 引入query-string库 import qs from 'query-string'const DetailData = https://www.it610.com/article/[ { 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

    React|React路由组件传参的三种方式——params、search、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 = https://www.it610.com/article/[ { id:'01', content: '你好,中国' }, { id: '02', content: '你好,程序员' }, { id: '03', content: '你好,csdn' } ] export default class Detail extends Component { render() { // 接收state参数 const { id, title } = this.props.location.stateconst 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. 路由链接(携带参数):to=“/demo/test/tom/18”>详情
    2. 注册路由(声明接收):path=“/demo/test/:name/:age” component={Test}/>
    3. 接收参数: this.props.match.params
    search参数:
    1. 路由链接(携带参数):to=“/demo/test?name=tom&age=18”>详情
    2. 注册路由(无需声明,正常注册即可):path=“/demo/test” component={Test}/>
    3. 接收参数: this.props.location.search
    4. 备注:获取到的search是urlencoded编码字符串,需要借助querystring解析。
    state参数:
    1. 路由链接(携带参数):to={{pathname:‘/demo/test’,state: {name: ‘tom’,age:18}}}>详情
    2. 注册路由(无需声明,正常注册即可):path=“/demo/test” component={Test}/>
    3. 接收参数: this.props.location.state
    4. 备注:如果不用BrowserRouter,刷新保留不住参数,因为BrowserRouter的history里保留了参数信息。
    今天的分享就到这里啦 ?
    如果对你有帮助的话,还请关注点赞收藏?评论哦
    不定时回访哟

      推荐阅读