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