withApi.tsx 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import * as React from 'react';
  2. import {Client} from 'app/api';
  3. import getDisplayName from 'app/utils/getDisplayName';
  4. type InjectedApiProps = {
  5. api: Client;
  6. };
  7. type WrappedProps<P> = Omit<P, keyof InjectedApiProps> & Partial<InjectedApiProps>;
  8. type OptionProps = {
  9. /**
  10. * Enabling this option will disable clearing in-flight requests when the
  11. * component is unmounted.
  12. *
  13. * This may be useful in situations where your component needs to finish up
  14. * some where the client was passed into some type of action creator and the
  15. * component is unmounted.
  16. */
  17. persistInFlight?: boolean;
  18. };
  19. /**
  20. * React Higher-Order Component (HoC) that provides "api" client when mounted,
  21. * and clears API requests when component is unmounted.
  22. */
  23. const withApi = <P extends InjectedApiProps>(
  24. WrappedComponent: React.ComponentType<P>,
  25. {persistInFlight}: OptionProps = {}
  26. ) =>
  27. class extends React.Component<WrappedProps<P>> {
  28. static displayName = `withApi(${getDisplayName(WrappedComponent)})`;
  29. constructor(props: WrappedProps<P>) {
  30. super(props);
  31. this.api = new Client();
  32. }
  33. componentWillUnmount() {
  34. if (!persistInFlight) {
  35. this.api.clear();
  36. }
  37. }
  38. private api: Client;
  39. render() {
  40. const {api, ...props} = this.props;
  41. return <WrappedComponent {...({api: api ?? this.api, ...props} as P)} />;
  42. }
  43. };
  44. export default withApi;