每天学点React - 路由组件参数传递的三种方式

130 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情

路由组件参数传递

前面我们学习了路由组件的使用,今天,我们来学学如何使用路由组件传递参数,通过点击路由链接将参数传递给组件页面进行渲染加载。

向路由组件传参的方式有如下几种:

  • params方式
  • search方式
  • state方式

params方式

params 方式,它是通过将具体的参数值拼接在路由链接上传递给组件的一种实现方式,传参方式稍微麻烦一些。

<Link to='/a/参数1/参数2'>{菜单名}</Link>

通过该方式进行参数的传递,我们还需要在注册路由时进行参数的声明。

<Route path='/a/:属性1/:属性2' component={A组件}/>

在A组件中,我们可以通过match属性得到传递过来的参数

const {params} = this.props.match

「案例代码」

「传参组件」

export default class D extends Component {

  state = {
    messageArr: [
      { id: '1', title: 'd_1' },
      { id: '2', title: 'd_2' },
      { id: '3', title: 'd_3' },
    ]
  }

  render() {
    const { messageArr } = this.state
    return (
      <div>
        <ul>
          {
            messageArr.map((message) => {
              return (
                <li key={message.id}>
                  {/* params方式传参 */}
                  <Link to={`/b/d/detail/${message.id}/${message.title}`}>{message.title}</Link>
                </li>
              )
            })
          }
        </ul>
        <hr/>
        {/* 申明接收params参数 */}
        <Route path='/b/d/detail/:id/:title' component={Detail}></Route>
      </div>
    )
  }
}

「接参组件」

const detailDate = [
  { id: '1', content: 'd_1展示区' },
  { id: '2', content: 'd_2展示区' },
  { id: '3', content: 'd_3展示区' },
]

export default class Detail extends Component {

  render() {
    console.log(this.props)
    
    // 接收params参数
    const {match:{params:{id, title}}} = this.props

    const findData = detailDate.find(detail => detail.id === id)
    return (
      <div>
        {title + ': ' + findData.content}
      </div>
    )
  }
}

「效果展示」 image.png

search方式

search 方式,跟我们平常使用的 get请求类似,通过?来进行参数拼接,在参数的传递上比较简单,但是接收参数时会麻烦一些。

<Link to={`/b/d/detail/?属性1=${参数1}&属性2=${参数2}`}>{菜单名}</Link>

使用该方式传递参数,注册路由时不需要做其它修改。

接收参数需要通过location属性来获取,需要注意的是,获取到的 searchurlencoded 编码字符串,需要借助 querystring 解析。

// qs引入
import qs from 'querystring'
// 或者
import qs from 'querystring-es3'

// 接收参数
const {search} = this.props.location
const {属性1, 属性2} = qs.parse(search.slice(1))

「案例代码」

「传参组件」

export default class D extends Component {

  state = {
    messageArr: [
      { id: '1', title: 'd_1' },
      { id: '2', title: 'd_2' },
      { id: '3', title: 'd_3' },
    ]
  }

  render() {
    const { messageArr } = this.state
    return (
      <div>
        <ul>
          {
            messageArr.map((message) => {
              return (
                <li key={message.id}>
                  {/* search方式传参 */}
                  <Link to={`/b/d/detail/?id=${message.id}&title=${message.title}`}>{message.title}</Link>
              )
            })
          }
        </ul>
        <hr/>
        {/* search 参数无需声明接收 */}
        <Route path='/b/d/detail' component={Detail}></Route>
      </div>
    )
  }
}

「接参组件」

const detailDate = [
  { id: '1', content: 'd_1展示区' },
  { id: '2', content: 'd_2展示区' },
  { id: '3', content: 'd_3展示区' },
]

export default class Detail extends Component {


  render() {
    console.log(this.props)
    // 接收search参数
    const {search} = this.props.location || {}
    const {id, title} = qs.parse(search.slice(1))

    const findData = detailDate.find(detail => detail.id === id) || {}
    return (
      <div>
        {title + ': ' + findData.content}
      </div>
    )
  }
}

「效果展示」

image.png

state方式

上面的两种方式均会在链接上显示我们所需传递的参数,那么,通过state的方式来实现,则可以达到隐藏参数的效果。

<Link to={{pathname: "/b/d/detail", state: {属性1: 参数1, 属性2: 参数2}}}>{菜单名}</Link>

通过这种方式实现,注册路由时不需要做其它修改。

接收参数需要通过location属性来获取。

const { state } = this.props.location

「案例代码」

「传参组件」

export default class D extends Component {

  state = {
    messageArr: [
      { id: '1', title: 'd_1' },
      { id: '2', title: 'd_2' },
      { id: '3', title: 'd_3' },
    ]
  }

  render() {
    const { messageArr } = this.state
    return (
      <div>
        <ul>
          {
            messageArr.map((message) => {
              return (
                <li key={message.id}>
                  {/* state方式传参 */}
                  <Link to={{pathname: "/b/d/detail", state: {id: message.id, title: message.title}}}>{message.title}</Link>
                </li>
              )
            })
          }
        </ul>
        <hr/>
        {/* state 参数无需声明接收 */}
        <Route path='/b/d/detail/:id/:title' component={Detail}></Route>
      </div>
    )
  }
}

「接参组件」

export default class Detail extends Component {

  render() {
    console.log(this.props)

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

    const findData = detailDate.find(detail => detail.id === id) || {}
    return (
      <div>
        {title + ': ' + findData.content}
      </div>
    )
  }
}

「效果展示」

image.png