0
点赞
收藏
分享

微信扫一扫

【React】一文搞懂路由组件传参(三种方案params、search、state)

慎壹 2022-07-18 阅读 73

前言

向路由组件传递params参数

示例:
在这里插入图片描述
在这里插入图片描述

  1. 点击导航栏message001,路径变为
    localhost:3000/home/message/detail/01/message001。
  2. 不点击时,路由组件Detail不显示;例如,点击导航栏对应的message001,则Detail组件显示内容为message001对应内容。
  3. 路由组件Detail是一个通用组件,内部显示什么内容由点击的导航栏决定;点击哪一个导航,就将哪一个导航的内容通过params传递给Detail组件。
  4. 例如,点击message002,将message002的id与title传入Detail组件,以供Detail组件显示对应002这个id的CONTENT内容。

示例重点在于:Message组件本身是一个路由组件,其又是Detail组件的父组件,在Message组件中注册Detail子组件,点击导航栏对应链接,将对应的message消息内容传递给子路由组件Detail。然后Detail接收到父路由组件Message传递的params参数,将内容显示在页面对应位置中。

接下来展示Message与Detail组件源码:
Message组件源码:

import React, { Component } from 'react'
import { Route, Link } from 'react-router-dom'
import Detail from './Detail'

export default class Message extends Component {
  state = {
    messageArr: [
      { id: '01', title: 'message001' },
      { id: '02', title: 'message002' },
      { id: '03', title: 'message003' },
    ]
  }

  render() {
    return (
      <div>
        <ul>
          {
            this.state.messageArr.map((msgObj) => {
              return (
                <li key={msgObj.id}>
                  {/* 向Detail路由组件传递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组件源码:

import React, { Component } from 'react'

const Detaildata = [
  { id: '01', content: '你好,中国!' },
  { id: '02', content: '你好,李焕英!' },
  { id: '03', content: '你好,China!' }
]

export default class Detail extends Component {
  render() {
    const { match: { params: { id, title } } } = this.props
    const findContent = Detaildata.find((detailObj) => {
      return detailObj.id === id
    })
    return (
      <ul>
        <li>ID:{id}</li>
        <li>TITLE:{title}</li>
        <li>CONTENT:{findContent.content}</li>
      </ul>
    )
  }
}

Home组件源码:

import React, { Component } from 'react'
import { Route, Switch, Redirect } from 'react-router-dom'
import Message from './Message'
import News from './News'
import MyNavLink from '../../components/MyNavLink'

export default class Home extends Component {
  render() {
    // console.log('Home', this.props)
    return (
      <div>
        <h3>我是Home组件内容</h3>
        <div>
          <ul className='nav nav-tabs'>
            <li>
              <MyNavLink to="/home/news">News</MyNavLink>
            </li>
            <li>
              <MyNavLink to="/home/message">Message</MyNavLink>
            </li>
          </ul>
          {/* 注册路由 */}
          <Switch>
            <Route path="/home/news" component={News} />
            <Route path="/home/message" component={Message} />
            <Redirect to="/home/news" />
          </Switch>
        </div>
      </div>
    )
  }
}

路由组件传参——params总结:

向路由组件传递search参数

上面我们学会了向路由组件传递params参数示例,我们还是运用这个示例,去体验一下向路由组件传递search参数。

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

向路由组件Detail传递search参数,比如点击message001,就将message001的id与title传入Detail组件的this.props.location.search中

在这里插入图片描述

在传递search参数时,不需要声明接收,只需要正常注册路由:

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

但是我们发现,this.props.location.search接收到的search参数是urlencoded格式的。

我们可以借助一个库,将urlencoded格式转化为object对象形式,从而拿到我们需要的id与title。

// 安装query-string库
npm i --save --include=dev query-string   //window
sudo npm i --save --include=dev query-string  //MAC

// 引入query-string
import qs from 'query-string'
// 将object转化为urlencoded
qs.stringify()

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

Detail组件源码:

import React, { Component } from 'react'
import qs from 'query-string'

const Detaildata = [
  { id: '01', content: '你好,中国!' },
  { id: '02', content: '你好,李焕英!' },
  { id: '03', content: '你好,China!' }
]

export default class Detail extends Component {
  render() {
    console.log(this.props)

    // 接收search参数
    const { location: { search } } = this.props
    const { id, title } = qs.parse(search)

    const findContent = Detaildata.find((detailObj) => {
      return detailObj.id === id
    })
    return (
      <ul>
        <li>ID:{id}</li>
        <li>TITLE:{title}</li>
        <li>CONTENT:{findContent.content}</li>
      </ul>
    )
  }
}

路由组件传参——search总结:

向路由组件传递state参数

上面学会了向路由组件传递params以及search参数,接下来还是运用这个案例去讲解向路由组件传递state参数。

{/* 向路由组件传递state参数 */}
{/* state参数是一个对象,对象有两个属性pathname和state */}
Link to={{ pathname: '/home/message/detail', state: { id: msgObj.id, title: msgObj.title } }}>
  {msgObj.title}
</Link>

我们可以看到,传递的state参数是一个对象,对象有两个属性分别是:pathname以及state。

参数就放在state这个对象中。

需要注意的是,⚠️state参数不显示在url地址栏中,而之前学习的params参数以及search参数都会在url地址栏中显示。

state参数与search参数一样,不需要声明接收,正常注册组件就好。

{/* 注册路由 */}
{/* state参数无需声明接收 */}
<Route path="/home/message/detail" component={Detail} />

在这里插入图片描述

那么接收state参数时,依旧是在this.props之中,this.props.location.state这个属性上有一个对象,对象中就是上级组件传递进路由组件的state参数。

我们的Detail路由组件可以这样接收state参数:

import React, { Component } from 'react'
const Detaildata = [
  { id: '01', content: '你好,中国!' },
  { id: '02', content: '你好,李焕英!' },
  { id: '03', content: '你好,China!' }
]

export default class Detail extends Component {
  render() {
    console.log(this.props)

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

    const findContent = Detaildata.find((detailObj) => {
      return detailObj.id === id
    })
    return (
      <ul>
        <li>ID:{id}</li>
        <li>TITLE:{title}</li>
        <li>CONTENT:{findContent.content}</li>
      </ul>
    )
  }
}

路由组件传参——state总结:

总结路由参数

向路由组件传递参数声明接收参数接受参数
params/demo/test/tom/18/demo/test/:name/:agethis.props.match.params
search/demo/test?name=tom&age=18/demo/test
(无需声明接收参数)
this.props.location.search
state{ pathname:‘/demo/test’,
state:{name:‘tom’,age:18} }
/demo/test
(无需声明接收参数)
this.props.location.state
举报

相关推荐

0 条评论