Skip to content

Commit a304fb6

Browse files
authored
Merge pull request #62227 from Krishna2323/krishna2323/issue/61751
2 parents 8815437 + 978d061 commit a304fb6

29 files changed

Lines changed: 113 additions & 102 deletions

.eslintrc.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,15 @@ const restrictedImportPaths = [
8787
importNames: ['memoize'],
8888
message: "Please use '@src/libs/memoize' instead.",
8989
},
90+
{
91+
name: 'lodash/isEqual',
92+
message: "Please use 'deepEqual' from 'fast-equals' instead.",
93+
},
94+
{
95+
name: 'lodash',
96+
importNames: ['isEqual'],
97+
message: "Please use 'deepEqual' from 'fast-equals' instead.",
98+
},
9099
{
91100
name: 'react-native-animatable',
92101
message: "Please use 'react-native-reanimated' instead.",

src/components/Attachments/AttachmentCarousel/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import isEqual from 'lodash/isEqual';
1+
import {deepEqual} from 'fast-equals';
22
import type {MutableRefObject} from 'react';
33
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
44
import type {ListRenderItemInfo} from 'react-native';
@@ -100,7 +100,7 @@ function AttachmentCarousel({report, attachmentID, source, onNavigate, setDownlo
100100
newAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.REPORT, {parentReportAction, reportActions: reportActions ?? undefined, report});
101101
}
102102

103-
if (isEqual(attachments, newAttachments)) {
103+
if (deepEqual(attachments, newAttachments)) {
104104
if (attachments.length === 0) {
105105
setPage(-1);
106106
setDownloadButtonVisibility?.(false);

src/components/Form/FormProvider.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {useFocusEffect} from '@react-navigation/native';
2-
import lodashIsEqual from 'lodash/isEqual';
2+
import {deepEqual} from 'fast-equals';
33
import type {ForwardedRef, MutableRefObject, ReactNode, RefAttributes} from 'react';
44
import React, {createRef, forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState} from 'react';
55
import {InteractionManager} from 'react-native';
@@ -194,7 +194,7 @@ function FormProvider(
194194

195195
const touchedInputErrors = Object.fromEntries(Object.entries(validateErrors).filter(([inputID]) => touchedInputs.current[inputID]));
196196

197-
if (!lodashIsEqual(errors, touchedInputErrors)) {
197+
if (!deepEqual(errors, touchedInputErrors)) {
198198
setErrors(touchedInputErrors);
199199
}
200200

src/components/MoneyRequestConfirmationList.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {useFocusEffect, useIsFocused} from '@react-navigation/native';
2-
import lodashIsEqual from 'lodash/isEqual';
2+
import {deepEqual} from 'fast-equals';
33
import React, {memo, useCallback, useEffect, useMemo, useRef, useState} from 'react';
44
import {InteractionManager, View} from 'react-native';
55
import type {OnyxEntry} from 'react-native-onyx';
@@ -1113,7 +1113,7 @@ MoneyRequestConfirmationList.displayName = 'MoneyRequestConfirmationList';
11131113
export default memo(
11141114
MoneyRequestConfirmationList,
11151115
(prevProps, nextProps) =>
1116-
lodashIsEqual(prevProps.transaction, nextProps.transaction) &&
1116+
deepEqual(prevProps.transaction, nextProps.transaction) &&
11171117
prevProps.onSendMoney === nextProps.onSendMoney &&
11181118
prevProps.onConfirm === nextProps.onConfirm &&
11191119
prevProps.iouType === nextProps.iouType &&
@@ -1125,8 +1125,8 @@ export default memo(
11251125
prevProps.isEditingSplitBill === nextProps.isEditingSplitBill &&
11261126
prevProps.iouCurrencyCode === nextProps.iouCurrencyCode &&
11271127
prevProps.iouMerchant === nextProps.iouMerchant &&
1128-
lodashIsEqual(prevProps.selectedParticipants, nextProps.selectedParticipants) &&
1129-
lodashIsEqual(prevProps.payeePersonalDetails, nextProps.payeePersonalDetails) &&
1128+
deepEqual(prevProps.selectedParticipants, nextProps.selectedParticipants) &&
1129+
deepEqual(prevProps.payeePersonalDetails, nextProps.payeePersonalDetails) &&
11301130
prevProps.isReadOnly === nextProps.isReadOnly &&
11311131
prevProps.bankAccountRoute === nextProps.bankAccountRoute &&
11321132
prevProps.policyID === nextProps.policyID &&
@@ -1140,6 +1140,6 @@ export default memo(
11401140
prevProps.onToggleBillable === nextProps.onToggleBillable &&
11411141
prevProps.hasSmartScanFailed === nextProps.hasSmartScanFailed &&
11421142
prevProps.reportActionID === nextProps.reportActionID &&
1143-
lodashIsEqual(prevProps.action, nextProps.action) &&
1143+
deepEqual(prevProps.action, nextProps.action) &&
11441144
prevProps.shouldDisplayReceipt === nextProps.shouldDisplayReceipt,
11451145
);

src/components/MoneyRequestConfirmationListFooter.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {format} from 'date-fns';
22
import {Str} from 'expensify-common';
3-
import lodashIsEqual from 'lodash/isEqual';
3+
import {deepEqual} from 'fast-equals';
44
import React, {memo, useMemo} from 'react';
55
import {View} from 'react-native';
66
import type {OnyxEntry} from 'react-native-onyx';
@@ -905,7 +905,7 @@ MoneyRequestConfirmationListFooter.displayName = 'MoneyRequestConfirmationListFo
905905
export default memo(
906906
MoneyRequestConfirmationListFooter,
907907
(prevProps, nextProps) =>
908-
lodashIsEqual(prevProps.action, nextProps.action) &&
908+
deepEqual(prevProps.action, nextProps.action) &&
909909
prevProps.currency === nextProps.currency &&
910910
prevProps.didConfirm === nextProps.didConfirm &&
911911
prevProps.distance === nextProps.distance &&
@@ -927,21 +927,21 @@ export default memo(
927927
prevProps.isReadOnly === nextProps.isReadOnly &&
928928
prevProps.isTypeInvoice === nextProps.isTypeInvoice &&
929929
prevProps.onToggleBillable === nextProps.onToggleBillable &&
930-
lodashIsEqual(prevProps.policy, nextProps.policy) &&
931-
lodashIsEqual(prevProps.policyTagLists, nextProps.policyTagLists) &&
930+
deepEqual(prevProps.policy, nextProps.policy) &&
931+
deepEqual(prevProps.policyTagLists, nextProps.policyTagLists) &&
932932
prevProps.rate === nextProps.rate &&
933933
prevProps.receiptFilename === nextProps.receiptFilename &&
934934
prevProps.receiptPath === nextProps.receiptPath &&
935935
prevProps.reportActionID === nextProps.reportActionID &&
936936
prevProps.reportID === nextProps.reportID &&
937-
lodashIsEqual(prevProps.selectedParticipants, nextProps.selectedParticipants) &&
937+
deepEqual(prevProps.selectedParticipants, nextProps.selectedParticipants) &&
938938
prevProps.shouldDisplayFieldError === nextProps.shouldDisplayFieldError &&
939939
prevProps.shouldDisplayReceipt === nextProps.shouldDisplayReceipt &&
940940
prevProps.shouldShowCategories === nextProps.shouldShowCategories &&
941941
prevProps.shouldShowMerchant === nextProps.shouldShowMerchant &&
942942
prevProps.shouldShowSmartScanFields === nextProps.shouldShowSmartScanFields &&
943943
prevProps.shouldShowTax === nextProps.shouldShowTax &&
944-
lodashIsEqual(prevProps.transaction, nextProps.transaction) &&
944+
deepEqual(prevProps.transaction, nextProps.transaction) &&
945945
prevProps.transactionID === nextProps.transactionID &&
946946
prevProps.unit === nextProps.unit,
947947
);

src/components/OptionRow.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import lodashIsEqual from 'lodash/isEqual';
1+
import {deepEqual} from 'fast-equals';
22
import React, {useEffect, useRef, useState} from 'react';
33
import type {StyleProp, TextStyle, ViewStyle} from 'react-native';
44
import {InteractionManager, StyleSheet, View} from 'react-native';
55
import useLocalize from '@hooks/useLocalize';
66
import useStyleUtils from '@hooks/useStyleUtils';
77
import useTheme from '@hooks/useTheme';
88
import useThemeStyles from '@hooks/useThemeStyles';
9-
import * as OptionsListUtils from '@libs/OptionsListUtils';
10-
import * as ReportUtils from '@libs/ReportUtils';
9+
import {shouldOptionShowTooltip} from '@libs/OptionsListUtils';
10+
import {getDisplayNamesWithTooltips} from '@libs/ReportUtils';
1111
import type {OptionData} from '@libs/ReportUtils';
1212
import CONST from '@src/CONST';
1313
import Button from './Button';
@@ -149,7 +149,7 @@ function OptionRow({
149149
const firstIcon = option?.icons?.at(0);
150150

151151
// We only create tooltips for the first 10 users or so since some reports have hundreds of users, causing performance to degrade.
152-
const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips((option.participantsList ?? (option.accountID ? [option] : [])).slice(0, 10), shouldUseShortFormInTooltip);
152+
const displayNamesWithTooltips = getDisplayNamesWithTooltips((option.participantsList ?? (option.accountID ? [option] : [])).slice(0, 10), shouldUseShortFormInTooltip);
153153
let subscriptColor = theme.appBG;
154154
if (optionIsFocused) {
155155
subscriptColor = focusedBackgroundColor;
@@ -221,7 +221,7 @@ function OptionRow({
221221
icons={option.icons}
222222
size={CONST.AVATAR_SIZE.DEFAULT}
223223
secondAvatarStyle={[StyleUtils.getBackgroundAndBorderStyle(hovered && !optionIsFocused ? hoveredBackgroundColor : subscriptColor)]}
224-
shouldShowTooltip={showTitleTooltip && OptionsListUtils.shouldOptionShowTooltip(option)}
224+
shouldShowTooltip={showTitleTooltip && shouldOptionShowTooltip(option)}
225225
/>
226226
))}
227227
<View style={contentContainerStyles}>
@@ -358,7 +358,7 @@ export default React.memo(
358358
prevProps.showSelectedState === nextProps.showSelectedState &&
359359
prevProps.highlightSelected === nextProps.highlightSelected &&
360360
prevProps.showTitleTooltip === nextProps.showTitleTooltip &&
361-
lodashIsEqual(prevProps.option.icons, nextProps.option.icons) &&
361+
deepEqual(prevProps.option.icons, nextProps.option.icons) &&
362362
prevProps.optionIsFocused === nextProps.optionIsFocused &&
363363
prevProps.option.text === nextProps.option.text &&
364364
prevProps.option.alternateText === nextProps.option.alternateText &&
@@ -370,7 +370,7 @@ export default React.memo(
370370
prevProps.option.pendingAction === nextProps.option.pendingAction &&
371371
prevProps.option.customIcon === nextProps.option.customIcon &&
372372
prevProps.option.tabIndex === nextProps.option.tabIndex &&
373-
lodashIsEqual(prevProps.option.amountInputProps, nextProps.option.amountInputProps),
373+
deepEqual(prevProps.option.amountInputProps, nextProps.option.amountInputProps),
374374
);
375375

376376
export type {OptionRowProps};

src/components/PopoverMenu.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable react/jsx-props-no-spreading */
2-
import lodashIsEqual from 'lodash/isEqual';
2+
import {deepEqual} from 'fast-equals';
33
import type {ReactNode, RefObject} from 'react';
44
import React, {useCallback, useLayoutEffect, useMemo, useState} from 'react';
55
import {StyleSheet, View} from 'react-native';
@@ -443,13 +443,13 @@ PopoverMenu.displayName = 'PopoverMenu';
443443
export default React.memo(
444444
PopoverMenu,
445445
(prevProps, nextProps) =>
446-
lodashIsEqual(prevProps.menuItems, nextProps.menuItems) &&
446+
deepEqual(prevProps.menuItems, nextProps.menuItems) &&
447447
prevProps.isVisible === nextProps.isVisible &&
448-
lodashIsEqual(prevProps.anchorPosition, nextProps.anchorPosition) &&
448+
deepEqual(prevProps.anchorPosition, nextProps.anchorPosition) &&
449449
prevProps.anchorRef === nextProps.anchorRef &&
450450
prevProps.headerText === nextProps.headerText &&
451451
prevProps.fromSidebarMediumScreen === nextProps.fromSidebarMediumScreen &&
452-
lodashIsEqual(prevProps.anchorAlignment, nextProps.anchorAlignment) &&
452+
deepEqual(prevProps.anchorAlignment, nextProps.anchorAlignment) &&
453453
prevProps.animationIn === nextProps.animationIn &&
454454
prevProps.animationOut === nextProps.animationOut &&
455455
prevProps.animationInTiming === nextProps.animationInTiming &&

src/components/PopoverWithMeasuredContent.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import isEqual from 'lodash/isEqual';
1+
import {circularDeepEqual, deepEqual} from 'fast-equals';
22
import React, {useContext, useMemo, useState} from 'react';
33
import type {LayoutChangeEvent} from 'react-native';
44
import {View} from 'react-native';
@@ -90,8 +90,8 @@ function PopoverWithMeasuredContent({
9090

9191
if (!prevIsVisible && isVisible && isContentMeasured && !shouldSkipRemeasurement) {
9292
// Check if anything significant changed that would require re-measurement
93-
const hasAnchorPositionChanged = !isEqual(prevAnchorPosition, anchorPosition);
94-
const hasWindowSizeChanged = !isEqual(prevWindowDimensions, {windowWidth, windowHeight});
93+
const hasAnchorPositionChanged = !deepEqual(prevAnchorPosition, anchorPosition);
94+
const hasWindowSizeChanged = !deepEqual(prevWindowDimensions, {windowWidth, windowHeight});
9595
const hasStaticDimensions = popoverDimensions.width > 0 && popoverDimensions.height > 0;
9696

9797
// Only reset if:
@@ -238,7 +238,7 @@ export default React.memo(PopoverWithMeasuredContent, (prevProps, nextProps) =>
238238
if (prevProps.isVisible === nextProps.isVisible && nextProps.isVisible === false) {
239239
return true;
240240
}
241-
return isEqual(prevProps, nextProps);
241+
return circularDeepEqual(prevProps, nextProps);
242242
});
243243

244244
export type {PopoverWithMeasuredContentProps};

src/components/Search/SearchPageHeader/SearchPageHeaderInput.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {useIsFocused} from '@react-navigation/native';
2+
import {deepEqual} from 'fast-equals';
23
import isEmpty from 'lodash/isEmpty';
3-
import isEqual from 'lodash/isEqual';
44
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
55
import {View} from 'react-native';
66
import {useOnyx} from 'react-native-onyx';
@@ -155,7 +155,7 @@ function SearchPageHeaderInput({queryJSON, searchRouterListVisible, hideSearchRo
155155
setAutocompleteQueryValue(updatedUserQuery);
156156

157157
const updatedSubstitutionsMap = getUpdatedSubstitutionsMap(singleLineUserQuery, autocompleteSubstitutions);
158-
if (!isEqual(autocompleteSubstitutions, updatedSubstitutionsMap) && !isEmpty(updatedSubstitutionsMap)) {
158+
if (!deepEqual(autocompleteSubstitutions, updatedSubstitutionsMap) && !isEmpty(updatedSubstitutionsMap)) {
159159
setAutocompleteSubstitutions(updatedSubstitutionsMap);
160160
}
161161

src/components/Search/SearchRouter/SearchRouter.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {findFocusedRoute, useNavigationState} from '@react-navigation/native';
2-
import isEqual from 'lodash/isEqual';
2+
import {deepEqual} from 'fast-equals';
33
import React, {forwardRef, useCallback, useEffect, useRef, useState} from 'react';
44
import type {TextInputProps} from 'react-native';
55
import {InteractionManager, Keyboard, View} from 'react-native';
@@ -198,7 +198,7 @@ function SearchRouter({onRouterClose, shouldHideInputCaret, isSearchRouterDispla
198198
setAutocompleteQueryValue(updatedUserQuery);
199199

200200
const updatedSubstitutionsMap = getUpdatedSubstitutionsMap(singleLineUserQuery, autocompleteSubstitutions);
201-
if (!isEqual(autocompleteSubstitutions, updatedSubstitutionsMap)) {
201+
if (!deepEqual(autocompleteSubstitutions, updatedSubstitutionsMap)) {
202202
setAutocompleteSubstitutions(updatedSubstitutionsMap);
203203
}
204204

0 commit comments

Comments
 (0)