前言
向路由组件传递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内容。
示例重点在于: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/:age | this.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 |