diff --git a/src/pages/SearchPage.js b/src/pages/SearchPage.js
index 67d4ebb57876..2ee29380ff80 100755
--- a/src/pages/SearchPage.js
+++ b/src/pages/SearchPage.js
@@ -1,5 +1,5 @@
import _ from 'underscore';
-import React, {useCallback, useEffect, useState, useMemo} from 'react';
+import React, {Component} from 'react';
import {View} from 'react-native';
import PropTypes from 'prop-types';
import {withOnyx} from 'react-native-onyx';
@@ -9,15 +9,17 @@ import * as ReportUtils from '../libs/ReportUtils';
import ONYXKEYS from '../ONYXKEYS';
import styles from '../styles/styles';
import Navigation from '../libs/Navigation/Navigation';
+import withWindowDimensions, {windowDimensionsPropTypes} from '../components/withWindowDimensions';
import * as Report from '../libs/actions/Report';
import HeaderWithBackButton from '../components/HeaderWithBackButton';
import ScreenWrapper from '../components/ScreenWrapper';
import Timing from '../libs/actions/Timing';
import CONST from '../CONST';
+import withLocalize, {withLocalizePropTypes} from '../components/withLocalize';
+import compose from '../libs/compose';
import personalDetailsPropType from './personalDetailsPropType';
import reportPropTypes from './reportPropTypes';
import Performance from '../libs/Performance';
-import useLocalize from '../hooks/useLocalize';
const propTypes = {
/* Onyx Props */
@@ -30,6 +32,11 @@ const propTypes = {
/** All reports shared with the user */
reports: PropTypes.objectOf(reportPropTypes),
+
+ /** Window Dimensions Props */
+ ...windowDimensionsPropTypes,
+
+ ...withLocalizePropTypes,
};
const defaultProps = {
@@ -38,158 +45,172 @@ const defaultProps = {
reports: {},
};
-function SearchPage({betas, personalDetails, reports}) {
- // Data for initialization (runs only on the first render)
- const {
- recentReports: initialRecentReports,
- personalDetails: initialPersonalDetails,
- userToInvite: initialUserToInvite,
- // Ignoring the rule because in this case we need the data only initially
- // eslint-disable-next-line react-hooks/exhaustive-deps
- } = useMemo(() => OptionsListUtils.getSearchOptions(reports, personalDetails, '', betas), []);
-
- const [searchValue, setSearchValue] = useState('');
- const [searchOptions, setSearchOptions] = useState({
- recentReports: initialRecentReports,
- personalDetails: initialPersonalDetails,
- userToInvite: initialUserToInvite,
- });
-
- const {translate} = useLocalize();
-
- const updateOptions = useCallback(() => {
- const {
- recentReports: localRecentReports,
- personalDetails: localPersonalDetails,
- userToInvite: localUserToInvite,
- } = OptionsListUtils.getSearchOptions(reports, personalDetails, searchValue.trim(), betas);
-
- setSearchOptions({
- recentReports: localRecentReports,
- personalDetails: localPersonalDetails,
- userToInvite: localUserToInvite,
- });
- }, [reports, personalDetails, searchValue, betas]);
-
- const debouncedUpdateOptions = useMemo(() => _.debounce(updateOptions, 75), [updateOptions]);
+class SearchPage extends Component {
+ constructor(props) {
+ super(props);
- useEffect(() => {
Timing.start(CONST.TIMING.SEARCH_RENDER);
Performance.markStart(CONST.TIMING.SEARCH_RENDER);
- }, []);
- useEffect(() => {
- debouncedUpdateOptions();
- }, [searchValue, debouncedUpdateOptions]);
+ this.searchRendered = this.searchRendered.bind(this);
+ this.selectReport = this.selectReport.bind(this);
+ this.onChangeText = this.onChangeText.bind(this);
+ this.debouncedUpdateOptions = _.debounce(this.updateOptions.bind(this), 75);
+
+ const {recentReports, personalDetails, userToInvite} = OptionsListUtils.getSearchOptions(props.reports, props.personalDetails, '', props.betas);
+
+ this.state = {
+ searchValue: '',
+ recentReports,
+ personalDetails,
+ userToInvite,
+ };
+ }
+
+ componentDidUpdate(prevProps) {
+ if (_.isEqual(prevProps.reports, this.props.reports) && _.isEqual(prevProps.personalDetails, this.props.personalDetails)) {
+ return;
+ }
+ this.updateOptions();
+ }
+
+ onChangeText(searchValue = '') {
+ this.setState({searchValue}, this.debouncedUpdateOptions);
+ }
/**
* Returns the sections needed for the OptionsSelector
*
* @returns {Array}
*/
- const getSections = () => {
+ getSections() {
const sections = [];
let indexOffset = 0;
- if (searchOptions.recentReports.length > 0) {
+ if (this.state.recentReports.length > 0) {
sections.push({
- data: searchOptions.recentReports,
+ data: this.state.recentReports,
shouldShow: true,
indexOffset,
});
- indexOffset += searchOptions.recentReports.length;
+ indexOffset += this.state.recentReports.length;
}
- if (searchOptions.personalDetails.length > 0) {
+ if (this.state.personalDetails.length > 0) {
sections.push({
- data: searchOptions.personalDetails,
+ data: this.state.personalDetails,
shouldShow: true,
indexOffset,
});
- indexOffset += searchOptions.recentReports.length;
+ indexOffset += this.state.recentReports.length;
}
- if (searchOptions.userToInvite) {
+ if (this.state.userToInvite) {
sections.push({
- data: [searchOptions.userToInvite],
+ data: [this.state.userToInvite],
shouldShow: true,
indexOffset,
});
}
return sections;
- };
+ }
- const searchRendered = () => {
+ searchRendered() {
Timing.end(CONST.TIMING.SEARCH_RENDER);
Performance.markEnd(CONST.TIMING.SEARCH_RENDER);
- };
-
- const onChangeText = (value = '') => {
- setSearchValue(value);
- };
+ }
+
+ updateOptions() {
+ const {recentReports, personalDetails, userToInvite} = OptionsListUtils.getSearchOptions(
+ this.props.reports,
+ this.props.personalDetails,
+ this.state.searchValue.trim(),
+ this.props.betas,
+ );
+ this.setState({
+ userToInvite,
+ recentReports,
+ personalDetails,
+ });
+ }
/**
* Reset the search value and redirect to the selected report
*
* @param {Object} option
*/
- const selectReport = (option) => {
+ selectReport(option) {
if (!option) {
return;
}
+
if (option.reportID) {
- setSearchValue('');
- Navigation.dismissModal(option.reportID);
+ this.setState(
+ {
+ searchValue: '',
+ },
+ () => {
+ Navigation.dismissModal(option.reportID);
+ },
+ );
} else {
Report.navigateToAndOpenReport([option.login]);
}
- };
-
- const isOptionsDataReady = ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(personalDetails);
- const headerMessage = OptionsListUtils.getHeaderMessage(
- searchOptions.recentReports.length + searchOptions.personalDetails.length !== 0,
- Boolean(searchOptions.userToInvite),
- searchValue,
- );
- return (
-
- {({didScreenTransitionEnd, safeAreaPaddingBottomStyle}) => (
- <>
-
-
-
-
- >
- )}
-
- );
+ }
+
+ render() {
+ const sections = this.getSections();
+ const isOptionsDataReady = ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(this.props.personalDetails);
+ const headerMessage = OptionsListUtils.getHeaderMessage(
+ this.state.recentReports.length + this.state.personalDetails.length !== 0,
+ Boolean(this.state.userToInvite),
+ this.state.searchValue,
+ );
+
+ return (
+
+ {({didScreenTransitionEnd, safeAreaPaddingBottomStyle}) => (
+ <>
+
+
+
+
+ >
+ )}
+
+ );
+ }
}
SearchPage.propTypes = propTypes;
SearchPage.defaultProps = defaultProps;
-SearchPage.displayName = 'SearchPage';
-export default withOnyx({
- reports: {
- key: ONYXKEYS.COLLECTION.REPORT,
- },
- personalDetails: {
- key: ONYXKEYS.PERSONAL_DETAILS_LIST,
- },
- betas: {
- key: ONYXKEYS.BETAS,
- },
-})(SearchPage);
+
+export default compose(
+ withLocalize,
+ withWindowDimensions,
+ withOnyx({
+ reports: {
+ key: ONYXKEYS.COLLECTION.REPORT,
+ },
+ personalDetails: {
+ key: ONYXKEYS.PERSONAL_DETAILS_LIST,
+ },
+ betas: {
+ key: ONYXKEYS.BETAS,
+ },
+ }),
+)(SearchPage);