TypeScript 动态加载模块

核心方法是下面这个文件

这里要重点解释几个点

1. 方法 asyncComponent 的参数是一个名为 getComponent 的方法, 参数名是getComponent, 参数的类型是一个方法, 用  () => Promise<any> 表示

这个方法的返回值是一个Promise对象, 这个Promise可以包含任意 <any> 类型的对象

2. 这个方法的返回值是 AsyncComponent 类, 它是React.Component的子类

3. AsyncComponent 加载完成之后会在componentDidMount 中调用 (await getComponent()).default;

   getComponent() 也就是传入的参数方法, 根据参数的定义, 它一定会返回一个包含任意对象的Promise对象, 然后调用这个对象的default属性

4. render方法负责渲染这个await getComponent() 返回的Component对象

import * as React from "react";

 

export default function asyncComponent(getComponent: () => Promise<any>) {

  return class AsyncComponent extends React.Component {

    public static Component: React.ComponentType<any> | null = null;

    public state = { Component: AsyncComponent.Component };

 

    public async componentDidMount() {

      if (!this.state.Component) {

        const Component = (await getComponent()).default;

        AsyncComponent.Component = Component;

        this.setState({ Component });

      }

    }

 

    public render() {

      const { Component } = this.state;

      return Component && <Component {...this.props} />;

    }

  };

}

 

然后我们定义一个Helloworld组件用于测试

import * as React from "react";

 

class Helloworld extends React.Component<any> {

  public render() {

    return <div>helloworld</div>;

  }

}

 

export default Helloworld;

注意上面这个组件必需有default, 否则调用时会报错

在app组件中我们使用如下方式来调用它们

1. private Hello: any = asyncComponent(() => import(“./Helloworld”));

   通过调用asyncComponent 来获取 Hello 组件, 注意传入的参数是 () => import(“./Helloworld”) , 参数表示一个方法, 这个方法 调用import … 来返回一个Promise对象

import * as React from "react";

import "./App.css";

import asyncComponent from "./asyncComponent";

 

class App extends React.Component {

  private Hello: any = asyncComponent(() => import("./Helloworld"));

  public render() {

    console.log(this.Hello);

    return (

      <div>

        <this.Hello />

      </div>

    );

  }

}

 

export default App;

实际上这个例子是对router组件的一种再包装, 如果没有特殊用途不需要写的这么复杂,  但是对asyncComponent 稍微包装一下我们就可以容易的加入权限校验等扩展