<commit_before>import * as React from 'react';
import {
  // TODO Tidy order
  DispatchProps,
  InputComponent,
  InputComponentWithTransform,
  ExportedComponentProps,
  Id,
  getStringFromId,
  mapDispatchToProps,
  getComponentStateFromUIStateBranch,
  omitReduxUIProps,
  TransformPropsFunc
} from './utils';

export function addReduxUIState<TUIState, TProps>(
  id: Id<TProps>,
): (WrappedComponent: InputComponent<TUIState, TProps>) => React.ComponentClass<ExportedComponentProps & TProps>;

export function addReduxUIState<TUIState, TProps, TTransformedProps>(
  id: Id<TProps>,
  transformProps: TransformPropsFunc<TUIState, TProps, TTransformedProps>
): (WrappedComponent: InputComponentWithTransform<TUIState, TProps, TTransformedProps>) => (
  React.ComponentClass<ExportedComponentProps & TProps>
);

export function addReduxUIState<TUIState, TProps, TTransformedProps>(
  id: Id<TProps>,
  transformProps?: TransformPropsFunc<TUIState, TProps, TTransformedProps>
) {
  return (WrappedComponent: InputComponent<TUIState, TProps>): React.ComponentClass<ExportedComponentProps & TProps> => // tslint:disable-line:max-line-length
  class ExportedComponent extends React.PureComponent<TProps & ExportedComponentProps, {}> {
    static displayName = 'ReduxUIStateHOC';

    mappedDispatchProps: DispatchProps<TUIState>;

    constructor(props: ExportedComponentProps & TProps) {
      super(props);
      const missingReduxPropsMessage = 'This probably means you\'re using addReduxUIState rather than ' +
        'connectReduxUIState and havent passed the required props through in your component\'s mapStateToProps and' +
        'mapDispatchToProps functions.';

      if (!props.uiStateBranch) {
        throw new Error(`Cannot find uiStateBranch in props. ${missingReduxPropsMessage}`);
      }

      if (!props.dispatch) {
        throw new Error(`Cannot find dispatch in props. ${missingReduxPropsMessage}`);
      }

      const idString = this.getId();

      if (!idString) {
        throw new Error(`
          Cannot find id in the addReduxUISTate config.
          An id must be specified in order to uniquely identify a particular piece of ui state
        `);
      }

      this.mappedDispatchProps = mapDispatchToProps<TUIState, TProps>(this.props.dispatch, props, idString);
    }

    getId() {
      return getStringFromId<Readonly<TProps>>(id, this.props);
    }

    getComponentState() {
      return getComponentStateFromUIStateBranch<TUIState>(
        this.props.uiStateBranch, this.getId()
      );
    }

    shouldComponentUpdate(nextProps: ExportedComponentProps) {
      return getComponentStateFromUIStateBranch<TUIState>(
        nextProps.uiStateBranch, this.getId()
      ) !== this.getComponentState();
    }

    render() {
      const uiState = this.getComponentState();
      if (uiState) {
        const props = transformProps
          ? transformProps(uiState, this.mappedDispatchProps, this.props as Readonly<TProps>)
          : { uiState, ...this.mappedDispatchProps, ...omitReduxUIProps(this.props) };
        // TODO Remove the any below once TypeScript 2.4 emerges
        // https://github.com/Microsoft/TypeScript/pull/13288
        // tslint:disable-next-line:no-any
        return <WrappedComponent {...props as any} />;
      }

      return null;
    };
  };
}<commit_msg>Update dispatch props when id changes and tidy render<commit_after>import * as React from 'react';
import {
  // TODO Tidy order
  DispatchProps,
  InputComponent,
  InputComponentWithTransform,
  ExportedComponentProps,
  Id,
  getStringFromId,
  mapDispatchToProps,
  getComponentStateFromUIStateBranch,
  omitReduxUIProps,
  TransformPropsFunc
} from './utils';

export function addReduxUIState<TUIState, TProps>(
  id: Id<TProps>,
): (WrappedComponent: InputComponent<TUIState, TProps>) => React.ComponentClass<ExportedComponentProps & TProps>;

export function addReduxUIState<TUIState, TProps, TTransformedProps>(
  id: Id<TProps>,
  transformFunction: TransformPropsFunc<TUIState, TProps, TTransformedProps>
): (WrappedComponent: InputComponentWithTransform<TUIState, TProps, TTransformedProps>) => (
  React.ComponentClass<ExportedComponentProps & TProps>
);

export function addReduxUIState<TUIState, TProps, TTransformedProps>(
  id: Id<TProps>,
  transformProps?: TransformPropsFunc<TUIState, TProps, TTransformedProps>
) {
  return (WrappedComponent: InputComponent<TUIState, TProps>): React.ComponentClass<ExportedComponentProps & TProps> => // tslint:disable-line:max-line-length
  class ExportedComponent extends React.PureComponent<TProps & ExportedComponentProps, {}> {
    static displayName = 'ReduxUIStateHOC';

    mappedDispatchProps: DispatchProps<TUIState>;

    constructor(props: ExportedComponentProps & TProps) {
      super(props);
      const missingReduxPropsMessage = 'This probably means you\'re using addReduxUIState rather than ' +
        'connectReduxUIState and havent passed the required props through in your component\'s mapStateToProps and' +
        'mapDispatchToProps functions.';

      if (!props.uiStateBranch) {
        throw new Error(`Cannot find uiStateBranch in props. ${missingReduxPropsMessage}`);
      }

      if (!props.dispatch) {
        throw new Error(`Cannot find dispatch in props. ${missingReduxPropsMessage}`);
      }

      const idString = this.getId();

      if (!idString) {
        throw new Error(`
          Cannot find id in the addReduxUISTate config.
          An id must be specified in order to uniquely identify a particular piece of ui state
        `);
      }
      this.defineMappedDispatchProps(idString, props);
    }

    getId() {
      return getStringFromId<Readonly<TProps>>(id, this.props);
    }

    getComponentState() {
      return getComponentStateFromUIStateBranch<TUIState>(
        this.props.uiStateBranch, this.getId()
      );
    }

    defineMappedDispatchProps(idString: string, props: TProps & ExportedComponentProps) {
      this.mappedDispatchProps = mapDispatchToProps<TUIState, TProps>(props.dispatch, props, idString);
    }

    componentWillUpdate(nextProps: TProps & ExportedComponentProps) {
      // If the id changes update the dispatch props
      const nextIdString = getStringFromId<Readonly<TProps>>(id, nextProps);
      if (nextIdString !== getStringFromId<Readonly<TProps>>(id, this.props)) {
        this.defineMappedDispatchProps(nextIdString, nextProps);
      }
    }

    shouldComponentUpdate(nextProps: ExportedComponentProps & TProps) {
      return (
        getStringFromId<Readonly<TProps>>(id, nextProps) !== getStringFromId<Readonly<TProps>>(id, this.props)
        ||
        getComponentStateFromUIStateBranch<TUIState>(nextProps.uiStateBranch, this.getId()) !== this.getComponentState()
      );
    }

    render() {
      const uiState = this.getComponentState();
      if (uiState) {
        return (
          <WrappedComponent
          {
            ...(
              transformProps
                ? transformProps(uiState, this.mappedDispatchProps, omitReduxUIProps(this.props))
                : { uiState, ...this.mappedDispatchProps, ...omitReduxUIProps(this.props) }
            )
          }
          />
        );
      }

      return null;
    };
  };
}
{'fraction_non_alphanumeric': 0.10044150110375276, 'fraction_numerical': 0.0009657836644591612, 'mean_word_length': 3.6378758797184902, 'pattern_counts': {'":': 0, '<': 56, '<?xml version=': 0, '>': 62, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1646047', 'n_tokens_mistral': 2117, 'n_tokens_neox': 2078, 'n_words': 450}