本篇内容主要讲解“React路由组件传参的三种方式是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“React路由组件传参的三种方式是什么”吧!
向路由组件传递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里保留了参数信息。
到此,相信大家对“React路由组件传参的三种方式是什么”有了更深的了解,不妨来实际操作一番吧!这里是恰卡网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!