// @flow

import PropTypes from 'prop-types';
import * as React from 'react';

import { sendReportsActionTypes, sendReports } from '../actions/report-actions';
import { queuedReports } from '../selectors/socket-selectors';
import type { AppState } from '../types/redux-types';
import {
  type ClientReportCreationRequest,
  type ClearDeliveredReportsPayload,
  queuedClientReportCreationRequestPropType,
} from '../types/report-types';
import type { DispatchActionPromise } from '../utils/action-utils';
import { connect } from '../utils/redux-utils';

type Props = {|
  canSendReports: boolean,
  // Redux state
  queuedReports: $ReadOnlyArray<ClientReportCreationRequest>,
  // Redux dispatch functions
  dispatchActionPromise: DispatchActionPromise,
  // async functions that hit server APIs
  sendReports: (
    reports: $ReadOnlyArray<ClientReportCreationRequest>,
  ) => Promise<void>,
|};
class ReportHandler extends React.PureComponent<Props> {
  static propTypes = {
    canSendReports: PropTypes.bool.isRequired,
    queuedReports: PropTypes.arrayOf(queuedClientReportCreationRequestPropType)
      .isRequired,
    dispatchActionPromise: PropTypes.func.isRequired,
    sendReports: PropTypes.func.isRequired,
  };

  componentDidMount() {
    if (this.props.canSendReports) {
      this.dispatchSendReports(this.props.queuedReports);
    }
  }

  componentDidUpdate(prevProps: Props) {
    if (!this.props.canSendReports) {
      return;
    }

    const couldSend = prevProps.canSendReports;
    const curReports = this.props.queuedReports;
    if (!couldSend) {
      this.dispatchSendReports(curReports);
      return;
    }

    const prevReports = prevProps.queuedReports;
    if (curReports !== prevReports) {
      const prevResponses = new Set(prevReports);
      const newResponses = curReports.filter(
        (response) => !prevResponses.has(response),
      );
      this.dispatchSendReports(newResponses);
    }
  }

  render() {
    return null;
  }

  dispatchSendReports(reports: $ReadOnlyArray<ClientReportCreationRequest>) {
    if (reports.length === 0) {
      return;
    }
    this.props.dispatchActionPromise(
      sendReportsActionTypes,
      this.sendReports(reports),
    );
  }

  async sendReports(reports: $ReadOnlyArray<ClientReportCreationRequest>) {
    await this.props.sendReports(reports);
    return ({ reports }: ClearDeliveredReportsPayload);
  }
}

export default connect(
  (state: AppState) => ({
    queuedReports: queuedReports(state),
  }),
  { sendReports },
)(ReportHandler);

@@ -7,44 +7,8 @@
 ow%0A%0A
-import PropTypes from 'prop-types';%0A
 impo
@@ -132,32 +132,57 @@
 %7B queuedReports 
+as queuedReportsSelector 
 %7D from '../selec
@@ -209,62 +209,8 @@
 s';%0A
-import type %7B AppState %7D from '../types/redux-types';%0A
 impo
@@ -291,53 +291,8 @@
 ad,%0A
-  queuedClientReportCreationRequestPropType,%0A
 %7D fr
@@ -330,15 +330,45 @@
 ort 
+%7B%0A  
 type 
-%7B 
+DispatchActionPromise,%0A  use
 Disp
@@ -384,17 +384,35 @@
 nPromise
- 
+,%0A  useServerCall,%0A
 %7D from '
@@ -444,23 +444,27 @@
 mport %7B 
-conn
+useSel
 ect
+or
  %7D from 
@@ -493,16 +493,20 @@
 ;%0A%0Atype 
+Base
 Props = 
@@ -510,16 +510,17 @@
  = %7B%7C%0A  
++
 canSendR
@@ -540,27 +540,47 @@
 an,%0A
-  // Redux state
+%7C%7D;%0Atype Props = %7B%7C%0A  ...BaseProps,
 %0A  
++
 queu
@@ -641,38 +641,9 @@
 ,%0A  
-// Redux dispatch functions%0A  
++
 disp
@@ -690,50 +690,9 @@
 ,%0A  
-// async functions that hit server APIs%0A  
++
 send
@@ -847,281 +847,8 @@
 %3E %7B%0A
-  static propTypes = %7B%0A    canSendReports: PropTypes.bool.isRequired,%0A    queuedReports: PropTypes.arrayOf(queuedClientReportCreationRequestPropType)%0A      .isRequired,%0A    dispatchActionPromise: PropTypes.func.isRequired,%0A    sendReports: PropTypes.func.isRequired,%0A  %7D;%0A%0A
   co
@@ -2037,123 +2037,445 @@
 ult 
-connect(%0A  (state: AppState) =%3E (%7B%0A    queuedReports: queuedReports(state),%0A  %7D),%0A  %7B sendReports %7D,%0A)(ReportHandler
+React.memo%3CBaseProps%3E(function ConnectedReportHandler(%0A  props: BaseProps,%0A) %7B%0A  const queuedReports = useSelector(queuedReportsSelector);%0A  const callSendReports = useServerCall(sendReports);%0A  const dispatchActionPromise = useDispatchActionPromise();%0A%0A  return (%0A    %3CReportHandler%0A      %7B...props%7D%0A      queuedReports=%7BqueuedReports%7D%0A      sendReports=%7BcallSendReports%7D%0A      dispatchActionPromise=%7BdispatchActionPromise%7D%0A    /%3E%0A  );%0A%7D
 );%0A

Use hook instead of connect function in ReportHandler