美文网首页
react-router4.x 按需加载的实现方式

react-router4.x 按需加载的实现方式

作者: _花 | 来源:发表于2018-09-29 14:00 被阅读0次

    第一种 create-react-app文档给的react-router按需加载实现:

    • 创建一个异步组件 AsyncComponent
    import React from 'react';
    
    export default function (getComponent) {
      return class AsyncComponent extends React.Component {
        static Component = null;
        state = { Component: AsyncComponent.Component };
    
        componentWillMount() {
          if (!this.state.Component) {
            getComponent().then(({default: Component}) => {
              AsyncComponent.Component = Component
              this.setState({ Component })
            })
          }
        }
        render() {
          const { Component } = this.state
          if (Component) {
            return <Component {...this.props} />
          }
          return null
        }
      }
    }
    
    • 使用异步组件:我们将使用asyncComponent动态导入我们想要的组件。
    import asyncComponent from './asyncComponent'
    const Login = asyncComponent(() => load('login/login'))
    const LayoutPage = asyncComponent(() => load('layout/layout'))
    const NoticeDeatil = asyncComponent(() => load('noticeDetail/noticeDetail'))
    export const appRouterMap = [
        {path:"/login",name:"Login",component:Login,auth:false},
        {path:"/web",name:"LayoutPage",component:LayoutPage,auth:false},
        {path:"/notice/:id",name:"NoticeDeatil",component:NoticeDeatil,auth:false},
    ]
    

    第二种 借助react-loadable来实现按需加载

    利用react-loadable这个高级组件,要做到实现按需加载这一点,我们将使用的WebPack,babel-plugin-syntax-dynamic-importreact-loadable

    npm i --save-dev babel-plugin-syntax-dynamic-import
    npm i --save-dev react-loadable

     .babelrc:       
     {          
       “ presets ”:[  “ react ” ],
      “ plugins ”:[  “ syntax-dynamic-import  ]  
      }
    
    
    import Loadable from 'react-loadable';
    import Loading from './Load';
    function load(component) {
      return import(`$pages/${component}`)//$pages在webpack里面配置过是“./src/pages”的别名
    }
    const Login = Loadable({  loader: () => load('login/login'), loading: Loading});//loading属性必须有
    const LayoutPage = Loadable({  loader: () => load('layout/layout'), loading: Loading,});
    const NoticeDeatil = Loadable({  loader: () => load('noticeDetail/noticeDetail'), loading: Loading,});
    export const appRouterMap = [
        {path:"/login",name:"Login",component:Login,auth:false},
        {path:"/web",name:"LayoutPage",component:LayoutPage,auth:false},
        {path:"/notice/:id",name:"NoticeDeatil",component:NoticeDeatil,auth:false},
    ]
    
    const {match, changeSidebar} = this.props;
    if (match.isExact) {
      changeSidebar('charts');
    }
    

    出现问题

    使用react-loadable之前可以正常获取exact属性,而在使用react-loadable包裹需要懒加载的组件后exact属性便无法获取。在网上没有找到解决方案,思考后发现:

    1. react-router4中每个路由也是一个组件,exact属性是从路由<Router>组件中传递给子组件的props
    2. react-loadable创建了新的懒加载组件包裹了原组件,而<Router>组件又包裹了react-loadable生成的组件
    3. 所以问题就在于react-loadable生成的中间组件影响了react-router4的路由组件向我们的子组件传递props,所以要传递props给子组件,修正代码如下:
    // Dashboard
    const LoadableDashboard = Loadable({
      loader: () => import('../Dashboard'),
      loading: Loading
    });
    
    export class Dashboard extends React.Component {
      render() {
        return <LoadableDashboard {...this.props}/>    // 传递props
      }
    }
    

    第三种 bundle-loader 按需加载方式

    安装依赖

    npm install bundle-loader --save-dev
    具体方式参考:
    https://www.npmjs.com/package/bundle-loader
    https://blog.csdn.net/dKnightL/article/details/79261867

    个人感觉第三种方法 bundle-loader 复杂,推荐使用第二种

    相关文章

      网友评论

          本文标题:react-router4.x 按需加载的实现方式

          本文链接:https://www.haomeiwen.com/subject/folvoftx.html