PromiseRender.js 1.61 KB
Newer Older
dengxiaofeng's avatar
dengxiaofeng committed
1
import React from 'react';
邓晓峰's avatar
邓晓峰 committed
2

dengxiaofeng's avatar
dengxiaofeng committed
3 4
import { Spin } from 'antd';
import isEqual from 'lodash/isEqual';
邓晓峰's avatar
邓晓峰 committed
5

dengxiaofeng's avatar
dengxiaofeng committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
import { isComponentClass } from './Secured';

export default class PromiseRender extends React.Component {
  state = {
    component: () => null,
  };

  componentDidMount() {
    this.setRenderComponent(this.props);
  }

  shouldComponentUpdate(nextProps, nextState) {
    const { component } = this.state;
    if (!isEqual(nextProps, this.props)) {
      this.setRenderComponent(nextProps);
    }

    if (nextState.component !== component) return true;

    return false;
  }

  setRenderComponent(props) {
邓晓峰's avatar
邓晓峰 committed
29
    const ok = this.checkIsInstantiation(props.ok);
dengxiaofeng's avatar
dengxiaofeng committed
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
    const error = this.checkIsInstantiation(props.error);
    props.promise
      .then(() => {
        this.setState({
          component: ok,
        });
        return true;
      })
      .catch(() => {
        this.setState({
          component: error,
        });
      });
  }

  checkIsInstantiation(target) {
    if (isComponentClass(target)) {
      const Target = target;
      return props => <Target {...props} />;
    }

    if (React.isValidElement(target)) {
      return props => React.cloneElement(target, props);
    }

    return () => target;
  }

  render() {
邓晓峰's avatar
邓晓峰 committed
59
    // const {  } = this.state;
邓晓峰's avatar
邓晓峰 committed
60
    const { ok, error, promise, component, ...rest } = this.props;
邓晓峰's avatar
邓晓峰 committed
61 62
    return component ? (
      <component {...rest} />
dengxiaofeng's avatar
dengxiaofeng committed
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
    ) : (
      <div
        style={{
          width: '100%',
          height: '100%',
          margin: 'auto',
          paddingTop: 50,
          textAlign: 'center',
        }}
      >
        <Spin size="large" />
      </div>
    );
  }
}