PromiseRender.jsx 1.8 KB
Newer Older
徐立's avatar
徐立 committed
1 2 3 4 5 6
import React from 'react';
import { Spin } from 'antd';
import isEqual from 'lodash/isEqual';
import { isComponentClass } from './Secured'; // eslint-disable-next-line import/no-cycle

export default class PromiseRender extends React.Component {
7 8 9
	state = {
		component: () => null,
	};
徐立's avatar
徐立 committed
10

11 12 13
	componentDidMount() {
		this.setRenderComponent(this.props);
	}
徐立's avatar
徐立 committed
14

15 16
	shouldComponentUpdate = (nextProps, nextState) => {
		const { component } = this.state;
徐立's avatar
徐立 committed
17

18 19 20
		if (!isEqual(nextProps, this.props)) {
			this.setRenderComponent(nextProps);
		}
徐立's avatar
徐立 committed
21

22 23 24
		if (nextState.component !== component) return true;
		return false;
	}; // set render Component : ok or error
徐立's avatar
徐立 committed
25

26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
	setRenderComponent(props) {
		const ok = this.checkIsInstantiation(props.ok);
		const error = this.checkIsInstantiation(props.error);
		props.promise
			.then(() => {
				this.setState({
					component: ok,
				});
				return true;
			})
			.catch(() => {
				this.setState({
					component: error,
				});
			});
	} // Determine whether the incoming component has been instantiated
	// AuthorizedRoute is already instantiated
	// Authorized  render is already instantiated, children is no instantiated
	// Secured is not instantiated
徐立's avatar
徐立 committed
45

46 47 48 49 50
	checkIsInstantiation = (target) => {
		if (isComponentClass(target)) {
			const Target = target;
			return (props) => <Target {...props} />;
		}
徐立's avatar
徐立 committed
51

52 53 54
		if (React.isValidElement(target)) {
			return (props) => React.cloneElement(target, props);
		}
徐立's avatar
徐立 committed
55

56 57
		return () => target;
	};
徐立's avatar
徐立 committed
58

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