diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index a55d329f39ee..27f424ad1b70 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -1,6 +1,6 @@ import {FlashList} from '@shopify/flash-list'; import type {ReactElement} from 'react'; -import React, {useCallback} from 'react'; +import React, {memo, useCallback} from 'react'; import {StyleSheet, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import withCurrentReportID from '@components/withCurrentReportID'; @@ -158,7 +158,7 @@ export default withCurrentReportID( transactionViolations: { key: ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, }, - })(LHNOptionsList), + })(memo(LHNOptionsList)), ); export type {LHNOptionsListProps}; diff --git a/src/components/OptionsList/BaseOptionsList.tsx b/src/components/OptionsList/BaseOptionsList.tsx index 4a9df89ae644..575df128894a 100644 --- a/src/components/OptionsList/BaseOptionsList.tsx +++ b/src/components/OptionsList/BaseOptionsList.tsx @@ -1,6 +1,6 @@ import isEqual from 'lodash/isEqual'; import type {ForwardedRef} from 'react'; -import React, {forwardRef, memo, useEffect, useRef} from 'react'; +import React, {forwardRef, memo, useEffect, useMemo, useRef} from 'react'; import type {SectionListRenderItem} from 'react-native'; import {View} from 'react-native'; import OptionRow from '@components/OptionRow'; @@ -31,7 +31,7 @@ function BaseOptionsList( shouldHaveOptionSeparator = false, showTitleTooltip = false, optionHoveredStyle, - contentContainerStyles, + contentContainerStyles: contentContainerStylesProp, sectionHeaderStyle, showScrollIndicator = true, listContainerStyles: listContainerStylesProp, @@ -51,6 +51,7 @@ function BaseOptionsList( nestedScrollEnabled = true, bounces = true, renderFooterContent, + safeAreaPaddingBottomStyle, }: BaseOptionListProps, ref: ForwardedRef, ) { @@ -64,7 +65,8 @@ function BaseOptionsList( const previousSections = usePrevious(sections); const didLayout = useRef(false); - const listContainerStyles = listContainerStylesProp ?? [styles.flex1]; + const listContainerStyles = useMemo(() => listContainerStylesProp ?? [styles.flex1], [listContainerStylesProp, styles.flex1]); + const contentContainerStyles = useMemo(() => [safeAreaPaddingBottomStyle, contentContainerStylesProp], [contentContainerStylesProp, safeAreaPaddingBottomStyle]); /** * This helper function is used to memoize the computation needed for getItemLayout. It is run whenever section data changes. diff --git a/src/components/OptionsList/index.native.tsx b/src/components/OptionsList/index.native.tsx index bdcd0418a940..d4977f25f366 100644 --- a/src/components/OptionsList/index.native.tsx +++ b/src/components/OptionsList/index.native.tsx @@ -10,7 +10,7 @@ function OptionsList(props: OptionsListProps, ref: ForwardedRef // eslint-disable-next-line react/jsx-props-no-spreading {...props} ref={ref} - onScrollBeginDrag={() => Keyboard.dismiss()} + onScrollBeginDrag={Keyboard.dismiss} /> ); } diff --git a/src/pages/home/report/ReportActionsList.js b/src/pages/home/report/ReportActionsList.js index 2f9e3222206b..1da806b9c269 100644 --- a/src/pages/home/report/ReportActionsList.js +++ b/src/pages/home/report/ReportActionsList.js @@ -1,7 +1,7 @@ import {useRoute} from '@react-navigation/native'; import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; +import React, {memo, useCallback, useEffect, useMemo, useRef, useState} from 'react'; import {DeviceEventEmitter, InteractionManager} from 'react-native'; import Animated, {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; import _ from 'underscore'; @@ -515,4 +515,4 @@ ReportActionsList.propTypes = propTypes; ReportActionsList.defaultProps = defaultProps; ReportActionsList.displayName = 'ReportActionsList'; -export default compose(withWindowDimensions, withCurrentUserPersonalDetails)(ReportActionsList); +export default compose(withWindowDimensions, withCurrentUserPersonalDetails)(memo(ReportActionsList)); diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js index 62ff9426b4ae..064187855b57 100755 --- a/src/pages/home/report/ReportActionsView.js +++ b/src/pages/home/report/ReportActionsView.js @@ -1,7 +1,7 @@ import {useIsFocused} from '@react-navigation/native'; import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import React, {useContext, useEffect, useMemo, useRef} from 'react'; +import React, {useCallback, useContext, useEffect, useMemo, useRef} from 'react'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; import networkPropTypes from '@components/networkPropTypes'; @@ -173,25 +173,25 @@ function ReportActionsView(props) { } }, [props.report.pendingFields, didSubscribeToReportTypingEvents, reportID]); + const oldestReportAction = useMemo(() => _.last(props.reportActions), [props.reportActions]); + /** * Retrieves the next set of report actions for the chat once we are nearing the end of what we are currently * displaying. */ - const loadOlderChats = () => { + const loadOlderChats = useCallback(() => { // Only fetch more if we are neither already fetching (so that we don't initiate duplicate requests) nor offline. if (props.network.isOffline || props.isLoadingOlderReportActions) { return; } - const oldestReportAction = _.last(props.reportActions); - // Don't load more chats if we're already at the beginning of the chat history if (!oldestReportAction || oldestReportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) { return; } // Retrieve the next REPORT.ACTIONS.LIMIT sized page of comments Report.getOlderActions(reportID, oldestReportAction.reportActionID); - }; + }, [props.isLoadingOlderReportActions, props.network.isOffline, oldestReportAction, reportID]); /** * Retrieves the next set of report actions for the chat once we are nearing the end of what we are currently @@ -228,7 +228,7 @@ function ReportActionsView(props) { /** * Runs when the FlatList finishes laying out */ - const recordTimeToMeasureItemLayout = () => { + const recordTimeToMeasureItemLayout = useCallback(() => { if (didLayout.current) { return; } @@ -243,7 +243,7 @@ function ReportActionsView(props) { } else { Performance.markEnd(CONST.TIMING.SWITCH_REPORT); } - }; + }, [hasCachedActions]); // Comments have not loaded at all yet do nothing if (!_.size(props.reportActions)) { diff --git a/src/pages/home/sidebar/SidebarLinks.js b/src/pages/home/sidebar/SidebarLinks.js index 2fe44639e184..e78e656e0b7e 100644 --- a/src/pages/home/sidebar/SidebarLinks.js +++ b/src/pages/home/sidebar/SidebarLinks.js @@ -1,7 +1,7 @@ /* eslint-disable rulesdir/onyx-props-must-have-default */ import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import React, {useCallback, useEffect, useRef} from 'react'; +import React, {useCallback, useEffect, useMemo, useRef} from 'react'; import {InteractionManager, StyleSheet, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; @@ -131,6 +131,9 @@ function SidebarLinks({onLinkClick, insets, optionListItems, isLoading, priority const viewMode = priorityMode === CONST.PRIORITY_MODE.GSD ? CONST.OPTION_MODE.COMPACT : CONST.OPTION_MODE.DEFAULT; + // eslint-disable-next-line react-hooks/exhaustive-deps + const contentContainerStyles = useMemo(() => StyleSheet.flatten([styles.sidebarListContainer, {paddingBottom: StyleUtils.getSafeAreaMargins(insets).marginBottom}]), [insets]); + return (