PromiseRender.jsx 1.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import React from 'react';
  2. import { Spin } from 'antd';
  3. import isEqual from 'lodash/isEqual';
  4. import { isComponentClass } from './Secured'; // eslint-disable-next-line import/no-cycle
  5. export default class PromiseRender extends React.Component {
  6. state = {
  7. component: () => null,
  8. };
  9. componentDidMount() {
  10. this.setRenderComponent(this.props);
  11. }
  12. shouldComponentUpdate = (nextProps, nextState) => {
  13. const { component } = this.state;
  14. if (!isEqual(nextProps, this.props)) {
  15. this.setRenderComponent(nextProps);
  16. }
  17. if (nextState.component !== component) return true;
  18. return false;
  19. }; // set render Component : ok or error
  20. setRenderComponent(props) {
  21. const ok = this.checkIsInstantiation(props.ok);
  22. const error = this.checkIsInstantiation(props.error);
  23. props.promise
  24. .then(() => {
  25. this.setState({
  26. component: ok,
  27. });
  28. return true;
  29. })
  30. .catch(() => {
  31. this.setState({
  32. component: error,
  33. });
  34. });
  35. } // Determine whether the incoming component has been instantiated
  36. // AuthorizedRoute is already instantiated
  37. // Authorized render is already instantiated, children is no instantiated
  38. // Secured is not instantiated
  39. checkIsInstantiation = target => {
  40. if (isComponentClass(target)) {
  41. const Target = target;
  42. return props => <Target {...props} />;
  43. }
  44. if (React.isValidElement(target)) {
  45. return props => React.cloneElement(target, props);
  46. }
  47. return () => target;
  48. };
  49. render() {
  50. const { component: Component } = this.state;
  51. const { ok, error, promise, ...rest } = this.props;
  52. return Component ? (
  53. <Component {...rest} />
  54. ) : (
  55. <div
  56. style={{
  57. width: '100%',
  58. height: '100%',
  59. margin: 'auto',
  60. paddingTop: 50,
  61. textAlign: 'center',
  62. }}
  63. >
  64. <Spin size="large" />
  65. </div>
  66. );
  67. }
  68. }