美文网首页
react异步加载组件与代码分割

react异步加载组件与代码分割

作者: xiudaozhe | 来源:发表于2020-07-07 22:05 被阅读0次

    继续学习github高赞项目react-pxq

    项目router中引入了路由组件,使用了异步加载的模式

    import asyncComponent from '@/utils/asyncComponent';
    
    const record = asyncComponent(() => import("@/pages/record/record"));
    const helpcenter = asyncComponent(() => import("@/pages/helpcenter/helpcenter"));
    const production = asyncComponent(() => import("@/pages/production/production"));
    const balance = asyncComponent(() => import("@/pages/balance/balance"));
    

    异步加载组件后,打包后项目文件多了几个chunk.js。


    图片.png

    这些js文件在打开项目时并未加载,直到点击了相应路由后才进行加载。
    asyncComponent 函数的实现方式发现有很多。看了一些后发现还是项目中的最简洁。

    export default function asyncComponent(importComponent) {
      class AsyncComponent extends Component {
        constructor(props) {
          super(props);
    
          this.state = {
            component: null
          };
        }
    
        async componentDidMount() {
          const { default: component } = await importComponent();
    
          this.setState({component});
        }
    
        render() {
          const C = this.state.component;
    
          return C ? <C {...this.props} /> : null;
        }
      }
    
      return AsyncComponent;
    }
    

    发现函数中写了一个组件类,其生命周期函数componentDidMount加了es2017的async。
    原理是在需要的路由组件外包裹了一层AsyncComponent 组件,当AsyncComponent 组件渲染时,触发componentDidMount生命周期,componentDidMount生命周期中修改了state,导致render再次执行。而state中存储了需要加载的路由组件,在render中返回,触发渲染。
    在组件树中可见非异步组件直接在Route下


    图片.png
    而异步加载的组件会包裹在AsyncComponent中。 图片.png
    看完项目的小小功能点后,顺便复习了下webpack打包中的chunkFilename
    chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
    

    该配置控制着chunk文件的文件名,如上图在使用异步加载组件后多出的4个文件。

    学完这个后发现官网上有异步加载和代码分割的方案react.lazy Suspense。
    为react16.6加入,方法更加优雅。Suspense的fallback 属性可设置组件切换之间的短暂空白页面,如显示loading

    import React, { Suspense } from 'react';
    
    const OtherComponent = React.lazy(() => import('./OtherComponent'));
    const AnotherComponent = React.lazy(() => import('./AnotherComponent'));
    
    function MyComponent() {
      return (
        <div>
          <Suspense fallback={<div>Loading...</div>}>
            <section>
              <OtherComponent />
              <AnotherComponent />
            </section>
          </Suspense>
        </div>
      );
    }
    

    下次再拜读源码

    相关文章

      网友评论

          本文标题:react异步加载组件与代码分割

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