第五章 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可以用于解决一些路径错误相关的问题。