connectWithCleanUp.tsx 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. import hoistNonReactStatics from 'hoist-non-react-statics';
  2. import React, { ComponentType, FunctionComponent, useEffect } from 'react';
  3. import { connect, MapDispatchToPropsParam, MapStateToPropsParam, useDispatch } from 'react-redux';
  4. import { cleanUpAction, StateSelector } from '../actions/cleanUp';
  5. export const connectWithCleanUp =
  6. <
  7. TStateProps extends {} = {},
  8. TDispatchProps = {},
  9. TOwnProps = {},
  10. State = {},
  11. TSelector extends object = {},
  12. Statics = {}
  13. >(
  14. mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>,
  15. mapDispatchToProps: MapDispatchToPropsParam<TDispatchProps, TOwnProps>,
  16. stateSelector: StateSelector<TSelector>
  17. ) =>
  18. (Component: ComponentType<any>) => {
  19. const ConnectedComponent = connect(
  20. mapStateToProps,
  21. mapDispatchToProps
  22. // @ts-ignore
  23. )(Component);
  24. const ConnectedComponentWithCleanUp: FunctionComponent = (props) => {
  25. const dispatch = useDispatch();
  26. useEffect(() => {
  27. return function cleanUp() {
  28. dispatch(cleanUpAction({ stateSelector }));
  29. };
  30. }, [dispatch]);
  31. // @ts-ignore
  32. return <ConnectedComponent {...props} />;
  33. };
  34. ConnectedComponentWithCleanUp.displayName = `ConnectWithCleanUp(${ConnectedComponent.displayName})`;
  35. hoistNonReactStatics(ConnectedComponentWithCleanUp, Component);
  36. type Hoisted = typeof ConnectedComponentWithCleanUp & Statics;
  37. return ConnectedComponentWithCleanUp as Hoisted;
  38. };