Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor ReportScreenWrapper to functional component #22260

Merged
merged 12 commits into from
Jul 13, 2023
76 changes: 22 additions & 54 deletions src/libs/Navigation/AppNavigator/ReportScreenWrapper.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
import React, {Component} from 'react';
import React, {useEffect} from 'react';
import PropTypes from 'prop-types';
import lodashGet from 'lodash/get';
import {withOnyx} from 'react-native-onyx';

import ONYXKEYS from '../../../ONYXKEYS';
import Permissions from '../../Permissions';

import ReportScreen from '../../../pages/home/ReportScreen';
import * as ReportUtils from '../../ReportUtils';
import reportPropTypes from '../../../pages/reportPropTypes';
import FullScreenLoadingIndicator from '../../../components/FullscreenLoadingIndicator';
import {withNavigationPropTypes} from '../../../components/withNavigation';
import * as App from '../../actions/App';
import usePermissions from '../../../hooks/usePermissions';

const propTypes = {
/** Available reports that would be displayed in this navigator */
reports: PropTypes.objectOf(reportPropTypes),

/** Beta features list */
betas: PropTypes.arrayOf(PropTypes.string),

/** The policies which the user has access to */
policies: PropTypes.objectOf(
PropTypes.shape({
Expand Down Expand Up @@ -50,7 +46,6 @@ const propTypes = {

const defaultProps = {
reports: {},
betas: [],
policies: {},
isFirstTimeNewExpensifyUser: false,
};
Expand All @@ -72,61 +67,37 @@ const getLastAccessedReportID = (reports, ignoreDefaultRooms, policies, isFirstT
};

// This wrapper is reponsible for opening the last accessed report if there is no reportID specified in the route params
class ReportScreenWrapper extends Component {
constructor(props) {
super(props);
function ReportScreenWrapper(props) {
const {canUseDefaultRooms} = usePermissions();

// If there is no reportID in route, try to find last accessed and use it for setParams
if (!lodashGet(this.props.route, 'params.reportID', null)) {
const reportID = getLastAccessedReportID(
this.props.reports,
!Permissions.canUseDefaultRooms(this.props.betas),
this.props.policies,
this.props.isFirstTimeNewExpensifyUser,
this.props.route.params.openOnAdminRoom,
);

// It's possible that props.reports aren't fully loaded yet
// in that case the reportID is undefined
if (reportID) {
this.props.navigation.setParams({reportID: String(reportID)});
} else {
App.confirmReadyToOpenApp();
}
}
}

shouldComponentUpdate(nextProps) {
useEffect(() => {
// Don't update if there is a reportID in the params already
if (lodashGet(this.props.route, 'params.reportID', null)) {
if (lodashGet(props.route, 'params.reportID', null)) {
App.confirmReadyToOpenApp();
return false;
return;
}

// If the reports weren't fully loaded in the constructor,
// try to get and set reportID again
// If there is no reportID in route, try to find last accessed and use it for setParams
const reportID = getLastAccessedReportID(
nextProps.reports,
!Permissions.canUseDefaultRooms(nextProps.betas),
nextProps.policies,
lodashGet(nextProps, 'route.params.openOnAdminRoom', false),
props.reports,
!canUseDefaultRooms,
props.policies,
props.isFirstTimeNewExpensifyUser,
lodashGet(props.route, 'params.openOnAdminRoom', false),
);

// It's possible that props.reports aren't fully loaded yet
// in that case the reportID is undefined
if (reportID) {
this.props.navigation.setParams({reportID: String(reportID)});
return true;
}
return false;
}

render() {
// Wait until there is reportID in the route params
if (lodashGet(this.props.route, 'params.reportID', null)) {
return <ReportScreen route={this.props.route} />;
props.navigation.setParams({reportID: String(reportID)});
} else {
App.confirmReadyToOpenApp();
}
}, [props.route, props.navigation, props.reports, canUseDefaultRooms, props.policies, props.isFirstTimeNewExpensifyUser]);

return <FullScreenLoadingIndicator initialParams={this.props.route.params} />;
}
// The ReportScreen without the reportID set will display a skeleton
// until the reportID is loaded and set in the route param
return <ReportScreen route={props.route} />;
}

ReportScreenWrapper.propTypes = propTypes;
Expand All @@ -137,9 +108,6 @@ export default withOnyx({
reports: {
key: ONYXKEYS.COLLECTION.REPORT,
},
betas: {
key: ONYXKEYS.BETAS,
},
policies: {
key: ONYXKEYS.COLLECTION.POLICY,
},
Expand Down
4 changes: 2 additions & 2 deletions src/pages/home/ReportScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const propTypes = {

const defaultProps = {
isSidebarLoaded: false,
reportActions: {},
reportActions: [],
report: {
hasOutstandingIOU: false,
isLoadingReportActions: false,
Expand All @@ -113,7 +113,7 @@ const defaultProps = {
* @returns {String}
*/
function getReportID(route) {
return route.params.reportID.toString();
return String(lodashGet(route, 'params.reportID', null));
}

// Keep a reference to the list view height so we can use it when a new ReportScreen component mounts
Expand Down