美文网首页
React组件懒加载

React组件懒加载

作者: 我叫Aliya但是被占用了 | 来源:发表于2018-01-17 17:21 被阅读2746次

    转载自:https://segmentfault.com/a/1190000010640236

    bundle-loader

    新版的React建议我们使用bundle-loader进行代码的分离,下面我们看下它的用法:

    // 当你用到这个函数时,这个chunk才会被请求
    var waitForChunk = require("bundle-loader!./file.js");
    
    //  当请求的chunk加载完成才会执行传入的回调函数,并将请求的模块作为参数传入回调函数
    waitForChunk(function(file) {
        // 接收到懒加载模块,类似于下面代码
        // var file = require("./file.js");
    });
    

    这个插件使用非常简单,只是对require.ensure的封装,使用起来类似于AMD的方式,
    只需在回调函数里接收到懒加载的模块即可。


    结合React

    React 组件也是模块,因此可以使用bundle-loader进行代码分离,只是需要在合适的地方请求调用即可。

    怎样知道何时需要请求这个组件呢?社区建议的是先加载一个bundle容器组件(这个bundle容器组件本身非常小),当这个容器组件被渲染到dom时则可认为我们需要请求对应的懒加载组件了。

    我们可以为所有的懒加载组件封装一个通用的容器组件:
    (这里也有已经封装好的:react-lazy-bundle,直接安装即可)

    import React, { Component } from "react";
    
    class Bundle extends Component {
      state = {
        // 因为module被占用了,我们用mod定义变量
        mod: null
      };
    
      componentWillMount() {
        this.load(this.props);
      }
    
      componentWillReceiveProps(nextProps) {
        if (nextProps.load !== this.props.load) {
          this.load(nextProps);
        }
      }
    
      load(props) {
        this.setState({
          mod: null
        });
        props.load(mod => {
          this.setState({
            // 为了兼容es module 和 AMD module
            mod: mod.default ? mod.default : mod
          });
        });
      }
    
      render() {
        //若加载完成则渲染对应懒加载的组件,反之加载beforeLoad传入的组件
        return this.state.mod
          ? <this.state.mod {...this.props} />
          : <this.props.beforeLoad {...this.props} />;
      }
    }
    
    export default Bundle;
    

    如上封装,使用时我们只需如下即可:

    import React, { Component } from "react";
    import Bundle from "./Bundle";
    
    import Test from "bundle-loader?lazy&name=[name]!./test";
    
    const BeforeLoadComponent = props =>
      <div>
        before load {props.name}
      </div>;
    
    class HomePage extends Component {
      render() {
        return (
          <div>
            <Bundle name="flypie" load={Test} beforeLoad={BeforeLoadComponent} />
          </div>
        );
      }
    }
    
    export default HomePage;
    

    结合React Router

    结合React Router也非常简单,因为已经把Bundle作为Route的component参数了,
    所以要再封装一层,把load和beforeLoad预先传入即可。

    import Bundle from "./Bundle";
    import About from "bundle-loader?lazy&name=[name]!./About";
    
    const AboutWrapper = props => <Bundle load={About} {...props}/>;
    
    class App extends Component {
    
      render() {
        return (
          <div>
            <h1>Welcome!</h1>
            <Route path="/about" component={AboutWrapper}/>
          </div>
        )
      }
    }
    

    相关文章

      网友评论

          本文标题:React组件懒加载

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