第五章 React 路由
五、向路由组件传递参数数据
1. 效果
2. 代码 - 传递 params 参数
2.1 Message
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}>
{}
<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link>
</li>
)
})
}
</ul>
<hr />
{}
<Route path="/home/message/detail/:id/:title" component={Detail}/>
</div>
);
}
}
2.2 Detail
import React, { Component } from 'react'
const Detaildata = [
{id:'01', content:'你好,中国'},
{id:'02', content:'你好,小帽学堂'},
{id:'03', content:'你好,未来的自己'}
]
export default class Detail extends Component {
render() {
const {id, title} = this.props.match.params
const findResult = Detaildata.find((detailObj)=>{
return detailObj.id === id
})
return (
<ul>
<li>ID:{id}</li>
<li>Title:{title}</li>
<li>Content: {findResult.content}</li>
</ul>
)
}
}
3. 代码 - 传递 search 参数
3.1 Message
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}>
{}
{}
{}
<Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link>
</li>
)
})
}
</ul>
<hr />
{}
{}
{}
<Route path="/home/message/detail" component={Detail}/>
</div>
);
}
}
3.2 Detail
import React, { Component } from 'react'
import qs from 'querystring'
const Detaildata = [
{id:'01', content:'你好,中国'},
{id:'02', content:'你好,小帽学堂'},
{id:'03', content:'你好,未来的自己'}
]
export default class Detail extends Component {
render() {
const {search} = this.props.location
const {id, title} = qs.parse(search.slice(1))
const findResult = Detaildata.find((detailObj)=>{
return detailObj.id === id
})
return (
<ul>
<li>ID:{id}</li>
<li>Title:{title}</li>
<li>Content: {findResult.content}</li>
</ul>
)
}
}
4. 代码 - 传递 state 参数
4.1 Message
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}>
{}
{}
{}
{}
{}
<Link to={{pathname:'/home/message/detail', state:{id:msgObj.id, title: msgObj.title}}}>{msgObj.title}</Link>
</li>
)
})
}
</ul>
<hr />
{}
{}
{}
{}
{}
<Route path="/home/message/detail" component={Detail}/>
</div>
);
}
}
4.2 Detail
import React, { Component } from 'react'
const Detaildata = [
{id:'01', content:'你好,中国'},
{id:'02', content:'你好,小帽学堂'},
{id:'03', content:'你好,未来的自己'}
]
export default class Detail extends Component {
render() {
const {id, title} = this.props.location.state || {}
const findResult = Detaildata.find((detailObj)=>{
return detailObj.id === id
}) || {}
return (
<ul>
<li>ID:{id}</li>
<li>Title:{title}</li>
<li>Content: {findResult.content}</li>
</ul>
)
}
}
5. 总结
1.params参数
路由链接(携带参数):<Link to='/demo/test/tom/18'}>详情</Link>
注册路由(声明接收):<Route path="/demo/test/:name/:age" component={Test}/>
接收参数:this.props.match.params
2.search参数
路由链接(携带参数):<Link to='/demo/test?name=tom&age=18'}>详情</Link>
注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
接收参数:this.props.location.search
备注:获取到的search是urlencoded编码字符串,需要借助querystring解析
3.state参数
路由链接(携带参数):<Link to={{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>
注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
接收参数:this.props.location.state
备注:刷新也可以保留住参数
6. 代码 - push 与 replace 模式
Message
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}>
{}
{}
{}
{}
{}
<Link replace to={{pathname:'/home/message/detail', state:{id:msgObj.id, title: msgObj.title}}}>{msgObj.title}</Link>
</li>
)
})
}
</ul>
<hr />
{}
{}
{}
{}
{}
<Route path="/home/message/detail" component={Detail}/>
</div>
);
}
}
六、多种路由跳转方式
1. 效果
2. 代码 - 跳转 + 携带 params 参数
2.1 Message
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" },
],
};
pushShow = (id, title) => {
this.props.history.push(`/home/message/detail/${id}/${title}`)
}
replaceShow = (id, title) => {
this.props.history.replace(`/home/message/detail/${id}/${title}`)
}
render() {
const { messageArr } = this.state;
return (
<div>
<ul>
{messageArr.map((msgObj) => {
return (
<li key={msgObj.id}>
{}
<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>
{msgObj.title}
</Link>
<button onClick={()=>this.pushShow(msgObj.id, msgObj.title)}>push查看</button>
<button onClick={()=>this.replaceShow(msgObj.id, msgObj.title)}>replace查看</button>
</li>
);
})}
</ul>
<hr />
{}
<Route path="/home/message/detail/:id/:title" component={Detail} />
</div>
);
}
}
2.2 Detail
import React, { Component } from 'react'
const Detaildata = [
{id:'01', content:'你好,中国'},
{id:'02', content:'你好,小帽学堂'},
{id:'03', content:'你好,未来的自己'}
]
export default class Detail extends Component {
render() {
const {id, title} = this.props.match.params
const findResult = Detaildata.find((detailObj)=>{
return detailObj.id === id
}) || {}
return (
<ul>
<li>ID:{id}</li>
<li>Title:{title}</li>
<li>Content: {findResult.content}</li>
</ul>
)
}
}
3. 代码 - 跳转 + 携带 state 参数
3.1 Message
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" },
],
};
pushShow = (id, title) => {
this.props.history.push(`/home/message/detail`, {id,title})
}
replaceShow = (id, title) => {
this.props.history.replace(`/home/message/detail`, {id,title})
}
render() {
const { messageArr } = this.state;
return (
<div>
<ul>
{messageArr.map((msgObj) => {
return (
<li key={msgObj.id}>
{}
<Link to={{pathname:'/home/message/detail',state:{id:msgObj.id, title:msgObj.title}}}>{msgObj.title}</Link>
<button onClick={()=>this.pushShow(msgObj.id, msgObj.title)}>push查看</button>
<button onClick={()=>this.replaceShow(msgObj.id, msgObj.title)}>replace查看</button>
</li>
);
})}
</ul>
<hr />
{}
<Route path="/home/message/detail" component={Detail} />
</div>
);
}
}
3.2 Detail
import React, { Component } from 'react'
const Detaildata = [
{id:'01', content:'你好,中国'},
{id:'02', content:'你好,小帽学堂'},
{id:'03', content:'你好,未来的自己'}
]
export default class Detail extends Component {
render() {
const {id, title} = this.props.location.state
const findResult = Detaildata.find((detailObj)=>{
return detailObj.id === id
})
return (
<ul>
<li>ID:{id}</li>
<li>Title:{title}</li>
<li>Content: {findResult.content}</li>
</ul>
)
}
}
4. 代码 - 前进后退
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" },
],
};
pushShow = (id, title) => {
this.props.history.push(`/home/message/detail`, { id, title });
};
replaceShow = (id, title) => {
this.props.history.replace(`/home/message/detail`, { id, title });
};
back = () => {
this.props.history.goBack();
};
forward = () => {
this.props.history.goForward();
};
go = () => {
this.props.history.go(-2);
};
render() {
const { messageArr } = this.state;
return (
<div>
<ul>
{messageArr.map((msgObj) => {
return (
<li key={msgObj.id}>
{}
<Link
to={{
pathname: "/home/message/detail",
state: { id: msgObj.id, title: msgObj.title },
}}
>
{msgObj.title}
</Link>
<button onClick={() => this.pushShow(msgObj.id, msgObj.title)}>
push查看
</button>
<button
onClick={() => this.replaceShow(msgObj.id, msgObj.title)}
>
replace查看
</button>
</li>
);
})}
</ul>
<hr />
{}
<Route path="/home/message/detail" component={Detail} />
<button onClick={this.back}>回退</button>
<button onClick={this.forward}>前进</button>
<button onClick={this.go}>go</button>
</div>
);
}
}
5. 总结
借助this.prosp.history对象上的API对操作路由跳转、前进、后退
-this.prosp.history.push()
-this.prosp.history.replace()
-this.prosp.history.goBack()
-this.prosp.history.goForward()
-this.prosp.history.go()
6. withRouter 的使用
Header
import React, { Component } from 'react'
import {withRouter} from 'react-router-dom'
class Header extends Component {
back = ()=>{
this.props.history.goBack()
}
forward = ()=>{
this.props.history.goForward()
}
go = ()=>{
this.props.history.go(-2)
}
render() {
console.log('Header组件收到的props是',this.props);
return (
<div className="page-header">
<h2>React Router Demo</h2>
<button onClick={this.back}>回退</button>
<button onClick={this.forward}>前进</button>
<button onClick={this.go}>go</button>
</div>
)
}
}
export default withRouter(Header)
七、BrowserRouter 与 HashRouter 的区别
1.底层原理不一样:
BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。
HashRouter使用的是URL的哈希值。
2.path表现形式不一样
BrowserRouter的路径中没有
HashRouter的路径包含
3.刷新后对路由state参数的影响
(1).BrowserRouter没有任何影响,因为state保存在history对象中。
(2).HashRouter刷新后会导致路由state参数的丢失!!!
4.备注:HashRouter可以用于解决一些路径错误相关的问题。