• ReactRouter升级 v2 to v4


    概述

    react-router V4 相对于react-router V2 or V3 几乎是重写了, 新版的react-router更偏向于组件化(everything is component)。

    V4汲取了很多思想,路由即是组件,使路由更具声明式,且方便组合。如果你习惯使用react,那么一定会很快上手新版的react-router

    react-router V4 被一分为三: react-router-dom(for web)、react-router-native(for native)、react-router(core)。但如果仅在浏览器中使用的话,一般只需要用到react-router-dom就可以了。

    改动点

    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代替 onLeave

    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:

    import createHashHistory as history from 'history/createHashHistory';

    兼容处理

    因为要从react-router V2完全迁移到react-router V4工作量还是挺大的,一下子难以完全迁移,所以对某些地方做了兼容处理。

    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; 

    参考资料:

  • 相关阅读:
    css字体属性相关。
    子级用css float浮动 而父级div没高度不能自适应高度
    转载:基于Redis实现分布式锁
    LeetCode(53):最大子序和
    LeetCode(52):N皇后 II
    LeetCode(51):N皇后
    LeetCode(50):Pow(x, n)
    LeetCode(49): 字母异位词分组
    LeetCode(48):旋转图像
    LeetCode(47):全排列 II
  • 原文地址:https://www.cnblogs.com/libin-1/p/7067938.html
Copyright © 2020-2023  润新知