React 异步组件

React 通过react-loadable实现异步组件

在一般的react项目中在性能优化方面除了减少各种静态资源的体积外,还有一个效果显著的方式,异步加载组件,包括页面级组件(在路由中配置的),以及其他的体积较大的第三方组件(bizcharts,bScroll,...),本文会详细说明使用react-loadable来实现三种异步组件:

  1. 页面级组件(router.js引用的组件),普通的react组件
  2. bizcharts 组合的react组件
  3. bScroll 等非典型react组件(第三方类库)

准备

项目中安装 react-loadable ,babel插件安装 syntax-dynamic-import. react-loadable是通过webpack的异步import实现的
如果要实现非页面的组件加载,首先要在webpack配置中将相应的代码块分离出来,splitchunk!!! (例如,bizcharts 等代码库,需要在splitchunk中给个单独配置)

react-loadable的基本使用和概念,其中import中的webpackChunkName是异步文件的文件名。

现在我们来讲list页面实现异步组件,其中在Loadable方法的参数配置中,


import Loadable from 'react-loadable';
// 首次加载
const Loading = ({ isLoading, error }) => {
    if (isLoading) {
        return 
加载中...
; } else if (error) { return
页面加载出现问题, 请刷新后重试
; } return null; }; const AsyncList = Loadable({ loader: () => import(/* webpackChunkName: 'page_list' */'@pages/list'), loading: Loading });
  • loading 是一个接受状态对象的函数,isLoading和error属性,通过这两个属性来返回相应的过渡组件
  • loader 是一个返回import()调用的函数
  • render 如果loader中只是个普通的react组件这个办法不需要用到,但是如果加载js或者组件时一个组件的集合就需要用到,其中loaded是加载的文件的export结果,props 是Loadable函数返回组件接收的参数。
    const A = Loadable({
        loader,
        render: (loaded, props) => {
            const CurComponent = 条件?loaded.default : loaded.other
            return ;
        },
        loading,
    });
    

此时props就是{in:tue}

页面级组件(router.js引用的组件),普通的react组件

未使用react-loadable之前的页面,如下:


// 首次加载
import Index from '@pages/index';
import List from '@pages/list';



const Routes = () => (
    
        
        
    
);

现在我们来讲list页面实现异步组件,其中在Loadable方法的参数配置中,可以根据项目需要修改loading中的过渡效果

import Loadable from 'react-loadable';
// 首次加载
import Index from '@pages/index';

const Loading = ({ isLoading, error }) => {
    if (isLoading) {
        return 
加载中...
; } else if (error) { return
页面加载出现问题, 请刷新后重试
; } return null; }; const AsyncList = Loadable({ loader: () => import(/* webpackChunkName: 'page_list' */'@pages/list'), loading: Loading }); const Routes = () => (

如果加载的js是个组件的集合,例如components.jsx 文件

export A =()=>{
A
}; export B =()=>{
B
}; export C =()=>{
C
};

此时要加载A页面,需要在render函数中的loaded参数获得A属性即A组件

const AsyncA = Loadable({
    loader: () => import(/* webpackChunkName: 'page_list' */'@pages/list'),
    render: (loaded, props) => {
        const CurComponent = loaded.A; // A组件
        return ;
    },
    loading: Loading
});

普通的react组件的加载类似普通的页面的加载

bizcharts 的异步实现,bizcharts的export类似上面的组件的组合,一般项目中用到的图表每个都会写到单独处理的文件里,chartA.js chartB.js,...,每个chart文件大概这样子:

import React from 'react';
import { Chart, Geom, Axis, Tooltip, Label, Guide, } from 'bizcharts';
class Index extends React.Component {
    render()
        return (
            
); } } export default Index;

先写一个通用的异步加载chart的函数getBizcharts,loading和上文提到的一样,函数的参数ReactComponent 就是原来的chartA,chartB组件 render 函数中的loader就是bizchart对象,通过getBizcharts函数就可以在chartA的组件的props.bizchart中获取和原来一样的bizcharts组件。

import Loadable from 'react-loadable';
export const getBizcharts = (ReactComponent) => Loadable({
    loader: () => import(/* webpackChunkName: "bizcharts" */'bizcharts'),
    render: (loaded, props) => ,
    loading: Loading
});

这是图表组件的样子:

import React from 'react';
import { getBizcharts } from '@components/getAsyncComponent';
// import { Chart, Geom, Axis, Tooltip, Label, Guide, } from 'bizcharts';

class Index extends React.Component {
    render()
        const {
            Chart, Geom, Axis, Tooltip, Label, Guide,
        } = this.props.bizchart;
        return (
            
); } } export default getBizcharts(Index);

在render中通过props.bizchart获取bizchart组件,导出时调用getBizcharts方法

bScroll 等非react组件

如果该类组件的export 是一个单独的构造,就是在render的时候出入 loaded.default
如果是一个集合,可以直接出入,在使用的组件中获取

你可能感兴趣的:(React 异步组件)