1import { connect, MapDispatchToPropsParam, MapStateToPropsParam, useDispatch } from 'react-redux';
2import { cleanUpAction, StateSelector } from '../actions/cleanUp';
3import React, { ComponentType, FunctionComponent, useEffect } from 'react';
4import hoistNonReactStatics from 'hoist-non-react-statics';
5
6export const connectWithCleanUp = <
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) => (Component: ComponentType<any>) => {
18  const ConnectedComponent = connect(
19    mapStateToProps,
20    mapDispatchToProps
21    // @ts-ignore
22  )(Component);
23
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
35  ConnectedComponentWithCleanUp.displayName = `ConnectWithCleanUp(${ConnectedComponent.displayName})`;
36  hoistNonReactStatics(ConnectedComponentWithCleanUp, Component);
37  type Hoisted = typeof ConnectedComponentWithCleanUp & Statics;
38
39  return ConnectedComponentWithCleanUp as Hoisted;
40};
41