ReactRouter升級 v2 to v4

概述

react-router V4 相對於react-router V2 or V3 幾乎是重寫了, 新版的react-router更偏向於組件化(everything is component)。javascript

V4汲取了不少思想,路由便是組件,使路由更具聲明式,且方便組合。若是你習慣使用react,那麼必定會很快上手新版的react-routerjava

react-router V4 被一分爲三: react-router-dom(for web)、react-router-native(for native)、react-router(core)。但若是僅在瀏覽器中使用的話,通常只須要用到react-router-dom就能夠了。react

改動點

1. Router/Route 的改變

// V2 or V3 import { Router, Route, hashHistory } from 'react-router'; <Router history={hashHistory}> <Route path='/foo' component={Foo} /> <Route path='/bar' component={Bar} /> </Router>
// V4 Router組件裏只能渲染一個組件 import { HashRouter as Router, Route } from 'react-router-dom'; <Router> <div> <Route path='/foo' component={Foo} /> <Route path='/bar' component={Bar} /> </div> </Router>

2. 組件嵌套

// V2 or V3 路由組件嵌套 import { Router, Route, hashHistory } from 'react-router'; <Router history={hashHistory}> <Route path='/' component={App}> <Route path='foo' component={Foo} /> <Route path='bar' component={Bar} /> </Route> </Router>
// V4 Router 的路由組件嵌套 import { HashRouter as Router, Route, Switch } from 'react-router-dom'; <Router> <Route path="/" component={(props) => ( <App {...props}> <Switch> <Route path='/foo' component={Foo} /> <Route path='/bar' component={Bar} /> </Switch> </App> )}/> </Router>

3. 路由的生命週期

react-router V4中去掉了on****的路由生命週期的鉤子,可是你能夠在組件中用componentDidMount 或 componentWillMount代替 onEnter,能夠用componentWillUpdate 或 componentWillReceiveProps代替 onUpdate,你能夠用componentWillUnmount代替 onLeaveweb

4. Link

// V2 or V3 import { Link } from 'react-router'; // V4 import { Link } from 'react-router-dom';

5. history.push and history.replace

// V2 or V3 history.push({ pathname: '/home', query: { foo: 'test', bar: 'temp' } }); history.replace({ pathname: '/home', query: { foo: 'test', bar: 'temp' } }); // V4 history.push({ pathname: '/home', search: '?foo=test&bar=temp', }); history.replace({ pathname: '/home', search: '?foo=test&bar=temp', });

6. props.params

// V2 or V3 獲取params能夠這麼獲取 this.props.params // V4 this.props.match.params

7. location.query

// V2 or V3 獲取query能夠這麼獲取 this.props.location.query // V4 去掉了location.query,只能使用search來獲取,爲了讓其跟瀏覽器同樣 // 若是想要兼容之前的location.query,可使用query-string庫解析一下 // 如: queryString.parse(props.location.search) this.props.location.search

8. location.action

// V2 or V3 獲取location的action this.props.location.action // V4 去掉了location.action, 放在了history裏面 history.action

9.關於history

之前獲取react-router裏面的history庫,能夠這麼獲取:瀏覽器

import {hashHistory as history} from 'react-router';

react-router V4:react-router

import createHashHistory as history from 'history/createHashHistory';

兼容處理

由於要從react-router V2徹底遷移到react-router V4工做量仍是挺大的,一會兒難以徹底遷移,因此對某些地方作了兼容處理。app

history

import _ from 'lodash'; import queryString from 'query-string'; function processHistory(history) { const _push = history.push; const _replace = history.replace; history.push = function (one) { if (!_.isPlainObject(one)) { return _push.apply(this, arguments); } const o = Object.assign({}, one); if (o.query) { o.search = queryString.stringify(o.query); } _push.apply(this, [o]); }; history.replace = function (one) { if (!_.isPlainObject(one)) { return _replace.apply(this, arguments); } const o = Object.assign({}, one); if (o.query) { o.search = queryString.stringify(o.query); } _replace.apply(this, [o]); }; return history; } export default processHistory;

props

import queryString from 'query-string'; const processReactRouterProps = (props) => { const newProps = Object.assign({}, props); newProps.location.query = queryString.parse(props.location.search); newProps.location.action = newProps.history.action; newProps.params = props.match.params || {}; // 不止 || 是否有意義 return newProps; } export default processReactRouterProps; 

參考資料:dom

相關文章
相關標籤/搜索