1、問題由來react
最近準備上手react,下載了一個react+antd作的後臺管理demo玩耍了一下,發現使用的react-router v3,在v4已經發布這麼久的前提下繼續玩耍v3是如何也說不過去的,而後就順帶升級了一下,其中踩的一些坑總結一下給各位分享。git
2、v3到v4主要有哪些變化?github
1.萬物皆組件,因此v4只是一堆提供了導航功能的組件(還有若干對象和方法): web
react-router
React Router 核心redux
react-router-dom
web使用的版本(本文討論和使用的對象)segmentfault
react-router-native
用於 React Native 的 React Routerantd
react-router-redux
React Router 和 Redux 的集成react-router
react-router-config
靜態路由配置的小助手app
2.v3中的router被 BrowserRouter 和 HashRouter 取代,分別取代v4中的 history={browserHistory} 和 history={hashHistory} 代碼以下:dom
1 //v3寫法 2 import {Router, Route, hashHistory, IndexRedirect} from 'react-router'; 3 <Router history={hashHistory}> 4 <Route ...> 5 </Router> 6 7 8 //v4寫法 9 import {BrowserRouter as Router, Route, Switch} from 'react-router-dom'; 10 <Router> 11 <Switch> 12 <Route exact path='/' component={Login}/> 13 <Route path='/app' component={Layout}/> 14 <Route path='/login' component={Login}/> 15 </Switch> 16 </Router> 17 <Router>
3.v4 中已經沒有 <IndexRoute>
了,但能夠使用 <Route exact>
來達到一樣的效果,新增的<Switch>標籤,用於互斥路由;
4.再也不經過經過 <Route>
組件的嵌套來實現佈局和頁面嵌套,v3中將路由集中在一塊兒處理,即便分離到若干文件中,本質也是一個配置文件;v4中路由規則位於佈局和 UI 自己之間,由於route自己也是一個組件,因此咱們玩耍的demo中的嵌套router須要重寫了:
1 //v3路由 2 <Router history={hashHistory}> 3 <Route path={'/'} components={Page}> 4 <IndexRedirect to="/app/dashboard/index"/> 5 <Route path={'app'} component={App}> 6 ...... 7 </Route> 8 <Route path={'login'} components={Login}/> 9 <Route path={'404'} component={NotFound}/> 10 </Route> 11 </Router> 12 13 //v4中,咱們須要實現嵌套路由本質是將路由以組件的形式分散到須要匹配的地方 14 export default class App extends Component { 15 render() { 16 return ( 17 <div style={{height: '100%'}}> 18 <Router> 19 <Switch> 20 <Route exact path='/' component={Login}/> 21 <Route path='/app' component={Layout}/> 22 <Route path='/login' component={Login}/> 23 </Switch> 24 </Router> 25 </div> 26 ) 27 } 28 } 29 30 class Layout extends React.Component { 31 render() { 32 return ( 33 <Layout> 34 <Sider> 35 <Content style={{margin: '24px 16px', padding: 24, background: '#fff', minHeight: 280}}> 36 <Switch> 37 <Route path="/app/first" component={FirstPage}/> 38 <Route path="/app/second" component={SecondPage}/> 39 </Switch> 40 </Content> 41 </Sider> 42 </Layout> 43 ); 44 } 45 } 46 47 class FirstPage extends React.Component { 48 render() { 49 return ( 50 <div>這是第一個頁面</div> 51 ); 52 } 53 } 54 55 56 class SecondPage extends React.Component { 57 render() { 58 return ( 59 <div>這是第一個頁面</div> 60 ); 61 } 62 }
上面代碼若是暫時看不懂不要緊,咱們一步一步拆解,首先App做爲根組件初始化,這時候咱們有三個路由"/","/app","/login",因爲v4路由的包容性路由,凡是"/app/**"的路由將匹配到"/app",例如「/app/first」和「/app/second」都將匹配到「/app」,而exact的做用則是打破包容性路由規則,不然全部「/**」都將匹配到「/」,就沒其餘路由啥事兒了。
Layout做爲嵌套路由中處理不一樣佈局的子路由,例如咱們的demo中,做爲管理系統,必然有 login, data-list,data-detail等不一樣佈局的頁面,而data-list和data-detail具備相同的左側菜單欄和Header、Footer。Layout中引入公共的左側菜單欄和Header、Footer,數據頁面都匹配到這裏。固然若是展現數據須要多種佈局,徹底能夠Layout1,Layout2......
咱們的數據表有用戶表,訂單表,新聞表等等,FirstPage,SecondPage等就是這些具體業務數據的頁面,「/app/first」或者「/app/first」的匹配路徑:App->Layou->FirstPage,至此一個基本的嵌套路由就完成了,其餘複雜路由能夠同理擴展。