react异步加载组件

异步加载组件就是为了解决初始化页面加载慢,这个时候我们应该将代码进行分割,按需加载。

一、利用import() 编写 asyncComponent.js
es6提供import()函数,它是运行时执行,也就是说,什么时候运行到这一句,就会加载指定的模块。
import()返回一个 Promise 对象
asyncComponent.js

import React, { Component } from 'react';
const asyncComponent = (importComponent) => {
  return class extends Component {
    constructor() {
      super();
      this.state = {
        component: null
      }
    }
    componentDidMount() {
      importComponent()
        .then(cmp => {
          this.setState({ component: cmp.default }); //.default 是模块有default输出接口
        });
    }
    //或者使用async/await 写成
    /* async componentDidMount() {
      const { default: component } = await importComponent(); //解构
      this.setState({
        component: component
      });
    } */
    render() {
      const C = this.state.component;
      return C ? <C {...this.props} /> : null;
    }
  }
};
export default asyncComponent;

router.js

// 异步组件
import AsyncComponent from './asyncComponent.js';
// 组件页面
const Home = AsyncComponent(() => import(/* webpackChunkName: "Home" */ './Home/index.jsx'));
...
<Route path="/" exact component={Home} />

二、利用getComponent
对应于以前的 component 属性,但是这个方法是异步的,也就是当路由匹配时,才会调用这个方法。
如果需要返回多个子组件,则使用 getComponents 方法

这里面有个 require.ensure 方法
require.ensure(dependencies, callback, chunkName)
这是 webpack 提供的方法,这也是按需加载的核心方法。第一个参数是依赖,第二个是回调函数,第三个就是chunkName,用来指定这个 chunk file 的 name。

这里需要在 webpack.config.js 的 output 内加上 chunkFilename

output: {
    path: path.join(__dirname, '/../dist/assets'),
    filename: 'app.js',
    publicPath: defaultSettings.publicPath,
    // 添加 chunkFilename
    chunkFilename: '[name].[chunkhash:5].chunk.js',
},
1
2
3
4
5
6
7
name 是在代码里为创建的 chunk 指定的名字,如果代码中没指定则 webpack 默认分配 id 作为 name。
chunkhash 是文件的 hash 码,这里只使用前五位。

<Route path="/index" getComponent={home}/>
...
const home = (location, callback) => {
  require.ensure([], function (require) {
    callback(null, require('@pages/home').default)
  }, 'home')
}

如果你是使用 es6 的写法,也就是你的组件都是通过 export default 导出的,那么在 getComponent 方法里面需要加入.default。
如果你是使用 CommonJS 的写法,也就是通过 module.exports 导出的,那就无须加 .default 了。

三、react-async-component
原理就是方法一,安装引进来用就行了 npm i react-async-component …

四、react-loadable
基本用法
loadable.js

import React from 'react';
import Loadable from 'react-loadable';

const LoadableComponent = Loadable({
  loader: () => import('./home'),
  loading() {
      return <div>正在加载</div>
  }
});
export default () => <LoadableComponent/>

router.js

import Detail from './pages/home/loadable.js';
...
<Route path='/home' exact component={home}></Route>
1
2
3
基于react-loadable封装loadable.js,如果不封装,每个文件下都写一个,代码冗余。

import React from 'react';
import Loadable from 'react-loadable';

//通用的过场组件
const MyLoadingComponent = ({ isLoading, error }) => {
    // Handle the loading state
    if (isLoading) {
        return <div>Loading...</div>;
    }
    // Handle the error state
    else if (error) {
        return <div>Sorry, there was a problem loading the page.</div>;
    }
    else {
        return null;
    }
};

//过场组件默认采用通用的,若传入了loading,则采用传入的过场组件
export default (loader,loading = MyLoadingComponent)=>{
    return Loadable({
        loader,
        loading
    });
}

router.js

import loadable from './loadable'
const Home = loadable(()=>import('@pages/home'))
...
<Route path="/home" component={Home}/>
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值