第五章 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>
& nbsp; < button onClick= { ( ) => this . pushShow ( msgObj. id, msgObj. title) } > push查看< / button>
& nbsp; < 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>
& nbsp; < button onClick= { ( ) => this . pushShow ( msgObj. id, msgObj. title) } > push查看< / button>
& nbsp; < 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>
& nbsp;
< button onClick= { ( ) => this . pushShow ( msgObj. id, msgObj. title) } >
push查看
< / button>
& nbsp;
< 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> & nbsp;
< button onClick= { this . forward} > 前进< / button> & nbsp;
< 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> & nbsp;
< button onClick= { this . forward} > 前进< / button> & nbsp;
< 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可以用于解决一些路径错误相关的问题。