日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

React路由組件傳參的三種方式(params、search、state)_React

作者:蠟筆雛田學代碼 ? 更新時間: 2022-09-14 編程語言

??向路由組件傳遞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里保留了參數信息。

原文鏈接:https://blog.csdn.net/xuxuii/article/details/125757000

欄目分類
最近更新