安裝
npm install 'react-router-dom'
示例
import React from 'react'
import {HashRouter,Route,Link} from 'react-router-dom'
const Basic = () => (
<HashRouter>//容器組件
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/page1">Page1</Link></li>
<li><Link to="/page2">Page2</Link></li>
</ul>
<hr/>
<Route exact path="/" component={Home}/>
<Route path="/page1" component={Page1}/>
<Route path="/page2" component={Page2}/>
</div>
</HashRouter>
)
容器組件
react-router的容器組件篇裁,就是最外層包括所有路由的組件旁瘫,所有路由活動需要在容器組件中發(fā)生
容器組件主要包含BrowserRouter,HashRouter,MemoryRouter三個
- BrowserRouter: 瀏覽器自帶的H5 API,restful風格,需要配合后臺梗逮;
- HashRouter: 使用hash方式進行路由,路徑后均有#;
- MemoryRouter: 在內(nèi)存中管理history诗鸭,地址欄不會變化沮焕。在reactNative中使用弓坞。
注意事項
- 所有與路由有關(guān)的組件(Link隧甚、NavLink、Route渡冻、Switch)必須包裹在容器組件中
- 容器組件有且只能有一個子元素
容器組件的使用
ReactDOM.render(<Provider store={store}>{/*這是react-redux的容器組件*/}
<HashRouter>{/*這是react-router-dom的容器組件*/}
<div>{/*一個子元素*/}
{/*Nav:header導航區(qū)域*/}
<Nav></Nav>
{/*基于 HashRouter展示不同的頁面*/}
<Switch>{/*Switch就是在Switch的路由配置只能走一個*/}
<Route path='/' exact component={Home}></Route>
<Route path='/page1' component={Page1}></Route>
<Route path='/page2' component={Page2}></Route>
<Redirect to='/'></Redirect>{/*重定向到首頁 */}
</Switch>
</div>
</HashRouter>
</Provider>, document.querySelector('#root'));
Route組件
Route組件用于組件的顯示戚扳,Route組件上有path和component屬性,對應的path會顯示對應的component,路徑和組件產(chǎn)生對應的映射關(guān)系(和vue-router的配置文件+router-view類似菩帝,但這是組件)咖城。
<div>
<Route path='/' component={Home}></Route>
<Route path='/page1' component={Page1}></Route>
<Route path='/page2' component={Page2}></Route>
</div>
//以上代碼,當瀏覽器訪問/page1或者/page2路徑呼奢,都會渲染Home組件宜雀,因為先和‘/’匹配了
細節(jié)知識點
- component屬性:component能夠接受一個組件名,也可以接受一個函數(shù)
<Route path="/" exact render={()=><h1>首頁</h1>}/>
- 路由匹配的方式:要路徑開頭匹配成功既會顯示對應的組件握础,就是當訪問/page1路徑的時候會匹配 / 的路徑 辐董,解決辦法是 exact屬性
- exact:作用是嚴格匹配,路徑是什么就匹配什么禀综,避免路徑匹配不正確的問題
<div> <Route path='/' exact component={Home}></Route> <Route path='/page1' component={Page1}></Route> </div> //此時訪問'/page1'简烘,就不會再匹配‘/’了
Link組件和NavLink組件
Link組件
Link 組件是react-router中提供的路由切換的組件,基于它可以實現(xiàn)點擊的時候?qū)崿F(xiàn)路由的切換(相當于vue中的<vue-router>組件)
Link組件的屬性
- to:'/xxx?xxx=123' 跳轉(zhuǎn)到指定的路由地址
- to: {pathname:'/xxx',search:'xxx:123',state:''}//可以基于state的方式傳參
- replace 默認值false 是替換HISTORY stack中當前的地址(true) 還是追加一個新的地址 (默認是追加)
- 基于link組件渲染定枷,渲染后的結(jié)果是一個A標簽孤澎,to對應的信息最后會變成href的內(nèi)容
<Link to={{pathname:'/',search:'lx=logo'}} className="navbar">強國首頁</Link>
NavLink組件
NavLink組件和LINK類似,不同在于欠窒,NavLink組件在當前頁面地址和組件對應地址相吻合的時候覆旭,會默認給組件加一個active樣式,讓其有選中態(tài)(可以修改選中狀態(tài))
- activeClassName:把默認你加的active樣式類改為自己設(shè)定的(默認是active)
- activeStyle:給匹配的NavLink設(shè)置行內(nèi)樣式
- exact 控制匹配的時候是否嚴格匹配(和route的一樣)
- isActive:()=>{} 匹配成功后執(zhí)行對應函數(shù)(相當于路由的鉤子函數(shù))
<NavLinkto={{pathname:'/',search:'lx=logo'}} className="navbar">強國首頁</NavLink>
//匹配成功時岖妄,此元素會有active類名
//有時會有bug=>類名不切換型将,可以用hashChange事件監(jiān)聽或者使用withRouter
受路由控制組件
就是路由變化時,對應顯示隱藏的那些組件
- 只有當前頁面的 hash地址 和 路由指定的地址匹配荐虐,才會將對應的組件渲染(withRouter是沒有地址匹配七兜,都被模擬成受路由管控的)
class Nav extends React.Component{
render(){
return
<ul className="nav navbar-nav">
{/*NavLink不是點擊誰,誰就有選中樣式(但是可以路由切換)福扬,而是當前頁面的哈希后的地址和NavLink中的to進行比較腕铸,哪個匹配了惜犀,哪個才有選中樣式*/}
<li><NavLink exact to='/'>首頁</NavLink></li>
<li><NavLink to='/page1'>page1</NavLink></li>
</ul>
}
}
export default withRouter(connect()(Nav))
//withRouter的意思是把一個非路由管控的組件,模擬成路由管控的組件
- 路由切換的原理 凡是匹配的路由恬惯,都會把對應的組件內(nèi)容重新添加到頁面中向拆,相反亚茬,不匹配的都會在頁面中移除掉酪耳,下次 重新匹配上,需要重新渲染到頁面上刹缝,每一次路由切換(頁面的哈希路由地址改變)碗暗,都會從一級路由開始重新渲染
- 所有受路由管控的組件,在組件的 props上都添加了三個屬性(相當于vue-route中的路由對象:包含當前路由的所有信息)
路由對象中的 history梢夯、location言疗、 match、params
- history對象 (用于編程式導航)
let {history}=this.props;
history.go(n)//到任意有的記錄中
history.push() //追加一條記錄
history.replace()//不會追加記錄
history.goback()//回退
history.goforward()//前進
- location
let {location:{pathname,search,state}}=this.props;
pathname當前的hash路由地址
search查詢字符串
state 基于 redirect颂砸、link噪奄、nav-link中的to={},傳遞的是一個對象人乓,對象中編寫的state勤篮,就可以通過 loactuion.state獲取
- match 匹配動態(tài)路由的值主要使用 params動態(tài)路由參數(shù)
let {match:{params}}=this.props;
console.log(params.id)
//獲取的是動態(tài)路由匹配的一些結(jié)果,可用于動態(tài)傳參
二級路由
<Switch>
{/*進入客戶管理頁面,我們默認為其展示的就是List區(qū)域內(nèi)容,或者使用重定向也可以*/}
<Route path='/custom' exact component={List}></Route>
<Route path='/custom/list' component={List}></Route>
<Route path='/custom/create' component={Create}></Route>
<Route path='/custom/Detail/:id' component={Detail}></Route>
{/*進入客戶管理頁面色罚,我們默認為其展示的就是List區(qū)域內(nèi)容*/}
{/*<Redirect from='/custom' to='/custom/list'></Redirect>*/}
</Switch>
Switch組件碰缔,用于嵌套Route組件
- 和switch case一樣,只能 選擇一個戳护,避免一個路徑匹配多個組件
像這種情況金抡,可能都會被渲染到頁面上,此時Switch組件就有用了
<Route path="/about" component={About}/>
<Route path="/:user" component={User}/>
<Route component={NoMatch}/>{/*無論前邊路由是否匹配成功腌且,都會走這個*/}
路由數(shù)據(jù)傳輸方式
不推薦
- 本地存儲 localstroage
- redux存儲 (頁面刷新數(shù)據(jù)就沒了)
點擊列表中某一項的時候梗肝,把信息存儲到本地或者redux中,跳轉(zhuǎn)到詳情頁面铺董,把信息從本地或者redux中獲取即可
推薦
- 1.問號傳參
<Link to={{
pathname:'/home/user',
search:`?id=${item.id}`, //問號傳參
}}>問號傳參</Link>
受控組件中獲取參數(shù)通過 this.props.location.search
- 2.state傳值(一旦頁面刷新state傳的值就沒了)
<Link to={{
pathname:'/home/user',
state:{'id':item.id},
}}>state傳值</Link>
受控組件中獲取參數(shù)通過 this.props.location.state
- 3.URL地址參數(shù) path=‘/custom/detail/:id’
//動態(tài)路徑設(shè)置
<Link to={{
pathname:`/home/user/${item.id}`
}}>URL地址參數(shù)</Link>
//Route路徑配置
<Route path='/custom/Detail/:id' component={User}></Route>
//User組件內(nèi)獲取參數(shù)
this.props.match.params.id
路由重定向 Redirect
<Redirect from='/user' to='/user/list'></Redirect>
//from 從哪個路由 to定向到哪個路由
處理默認子路由
- Redirect
<Route path='/user/list' component={List}></Route>
<Redirect from='/user' to='/user/list'></Redirect>
//路徑 /user下的默認顯示的子路由是 /user/list 巫击,/user和/user/list 最后渲染的都是List組件
- 兩個路徑都指向一個組件
<Route path='/user' exact component={List}></Route>
<Route path='/user/list' component={List}></Route>