当前位置:首页 » 《随便一记》 » 正文

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

20 人参与  2022年08月12日 08:15  分类 : 《随便一记》  评论

点击全文阅读


前言

??欢迎来到我的博客??
?博主是一名大学在读本科生,主要学习方向是前端?。
?目前已经更新了【Vue】、【React–从基础到实战】、【TypeScript】等等系列专栏?
?目前正在学习的是? R e a c t 框架 React框架 React框架?,中间夹杂了一些基础知识的回顾⌨️
?博客主页?codeMak1r.的博客

??本文目录??

前言向路由组件传递params参数向路由组件传递search参数向路由组件传递state参数总结路由参数
本文被专栏【React–从基础到实战】收录

?坚持创作✏️,一起学习?,码出未来??‍?!
在这里插入图片描述

向路由组件传递params参数

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

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

项目结构

src

├─App.jsx├─index.js├─pages|   ├─Home|   |  ├─index.jsx|   |  ├─News|   |  |  └index.jsx|   |  ├─Message|   |  |    ├─index.jsx|   |  |    ├─Detail|   |  |    |   └index.jsx|   ├─About|   |   └index.jsx├─components|     ├─MyNavLink|     |     └index.jsx|     ├─Header|     |   └index.jsx

【分割线】

public

├─favicon.ico├─index.html├─css|  └bootstrap.css

示例重点在于: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总结:

在路由链接中向路由组件传递params参数

<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>  {msgObj.title}</Link>

注册路由(声明接收params参数)

{/* 声明接收params参数 */}<Route path="/home/message/detail/:id/:title" component={Detail} />

在路由组件中接受参数,路由组件的this.props.match.params中就可以接收到上级组件传递过来的params参数。

const { match: { params: { id, title } } } = this.props// 连续解构赋值

在这里插入图片描述

向路由组件传递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   //windowsudo npm i --save --include=dev query-string  //MAC// 引入query-stringimport qs from 'query-string'
// 将object转化为urlencodedqs.stringify()// 将urlencoded转化为objectqs.parse()
// 接收search参数const { location: { search } } = this.propsconst { 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总结:

在路由链接中向路由组件传递search参数

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

正常注册路由(无需声明接收search参数)

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

在路由组件中接受参数,路由组件的this.props.location.search中就可以接收到上级组件传递过来的search参数。

由于接受的search参数是urlencoded编码字符串,我们需要借助query-string这个库进行格式转换。

// 接收search参数const { location: { search } } = this.propsconst { id, title } = qs.parse(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总结:

在路由链接中向路由组件传递state参数

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

正常注册路由(无需声明接收state参数)

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

在路由组件中接受参数,路由组件的this.props.location.state中就可以接收到上级组件传递过来的state参数。

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

总结路由参数

向路由组件传递参数声明接收参数接受参数
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

??今天的小知识就分享到这里啦
如果觉得博主的文章还不错的话
可以给博主一个免费的关注,如果三连点赞?收藏支持的话就更好了
✏️原创不易你的支持将会是我最大的动力?
?感谢观看


点击全文阅读


本文链接:http://m.zhangshiyu.com/post/44287.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1