Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 51 additions & 51 deletions src/pages/workspace/accounting/qbd/QuickBooksDesktopSetupPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ function RequireQuickBooksDesktopModal({route}: RequireQuickBooksDesktopModalPro
const [codatSetupLink, setCodatSetupLink] = useState<string>('');
const hasResultOfFetchingSetupLink = !!codatSetupLink || hasError;

const ContentWrapper = hasResultOfFetchingSetupLink
? ({children}: React.PropsWithChildren) => children
: ({children}: React.PropsWithChildren) => <FullPageOfflineBlockingView addBottomSafeAreaPadding>{children}</FullPageOfflineBlockingView>;

const fetchSetupLink = useCallback(() => {
setHasError(false);
// eslint-disable-next-line rulesdir/no-thenable-actions-in-views
Expand Down Expand Up @@ -79,6 +75,56 @@ function RequireQuickBooksDesktopModal({route}: RequireQuickBooksDesktopModalPro

const shouldShowError = hasError;

const children = (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ PERF-4 (docs)

The children JSX element is not memoized and is passed to the memoized FullPageOfflineBlockingView component. Since the parent component is not optimized by React Compiler, this creates a new React element on every render, breaking memoization and causing unnecessary re-renders.

Suggested fix: Wrap the children declaration with useMemo:

const children = useMemo(() => (
    <>
        {shouldShowError && (
            // ... existing JSX
        )}
        {!shouldShowError && (
            // ... existing JSX
        )}
    </>
), [shouldShowError, hasResultOfFetchingSetupLink, codatSetupLink, styles, translate, illustrations, environmentURL, policyID]);

@aimane-chnaif aimane-chnaif Jan 13, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think react compiler already auto memoize this. So false alarm

<>
{shouldShowError && (
<View style={[styles.flex1, styles.justifyContentCenter, styles.alignItemsCenter, styles.ph5, styles.mb9]}>
<Icon
src={illustrations.BrokenMagnifyingGlass}
width={116}
height={168}
/>
<Text style={[styles.textHeadlineLineHeightXXL, styles.mt3]}>{translate('workspace.qbd.setupPage.setupErrorTitle')}</Text>
<View style={[styles.renderHTML, styles.ph5, styles.mv3]}>
<RenderHTML html={translate('workspace.qbd.setupPage.setupErrorBody', {conciergeLink: `${environmentURL}/${ROUTES.CONCIERGE}`})} />
</View>
</View>
)}
{!shouldShowError && (
<View style={[styles.flex1, styles.ph5]}>
<View style={[styles.alignSelfCenter, styles.computerIllustrationContainer, styles.pv6]}>
<ImageSVG src={illustrations.LaptopWithSecondScreenSync} />
</View>

<Text style={[styles.textHeadlineH1, styles.pt5]}>{translate('workspace.qbd.setupPage.title')}</Text>
<Text style={[styles.textSupporting, styles.textNormal, styles.pt4]}>{translate('workspace.qbd.setupPage.body')}</Text>
<View style={[styles.qbdSetupLinkBox, styles.mt5]}>
{!hasResultOfFetchingSetupLink ? (
<ActivityIndicator />
) : (
<CopyTextToClipboard
text={codatSetupLink}
textStyles={[styles.textSupporting]}
/>
)}
</View>
<FixedFooter
style={[styles.mtAuto, styles.ph0]}
addBottomSafeAreaPadding
>
<Button
success
text={translate('common.done')}
onPress={() => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_DESKTOP_TRIGGER_FIRST_SYNC.getRoute(policyID))}
pressOnEnter
large
/>
</FixedFooter>
</View>
)}
</>
);

return (
<ScreenWrapper
shouldEnablePickerAvoiding={false}
Expand All @@ -90,53 +136,7 @@ function RequireQuickBooksDesktopModal({route}: RequireQuickBooksDesktopModalPro
shouldShowBackButton
onBackButtonPress={() => Navigation.dismissModal()}
/>
<ContentWrapper>
{shouldShowError && (
<View style={[styles.flex1, styles.justifyContentCenter, styles.alignItemsCenter, styles.ph5, styles.mb9]}>
<Icon
src={illustrations.BrokenMagnifyingGlass}
width={116}
height={168}
/>
<Text style={[styles.textHeadlineLineHeightXXL, styles.mt3]}>{translate('workspace.qbd.setupPage.setupErrorTitle')}</Text>
<View style={[styles.renderHTML, styles.ph5, styles.mv3]}>
<RenderHTML html={translate('workspace.qbd.setupPage.setupErrorBody', {conciergeLink: `${environmentURL}/${ROUTES.CONCIERGE}`})} />
</View>
</View>
)}
{!shouldShowError && (
<View style={[styles.flex1, styles.ph5]}>
<View style={[styles.alignSelfCenter, styles.computerIllustrationContainer, styles.pv6]}>
<ImageSVG src={illustrations.LaptopWithSecondScreenSync} />
</View>

<Text style={[styles.textHeadlineH1, styles.pt5]}>{translate('workspace.qbd.setupPage.title')}</Text>
<Text style={[styles.textSupporting, styles.textNormal, styles.pt4]}>{translate('workspace.qbd.setupPage.body')}</Text>
<View style={[styles.qbdSetupLinkBox, styles.mt5]}>
{!hasResultOfFetchingSetupLink ? (
<ActivityIndicator />
) : (
<CopyTextToClipboard
text={codatSetupLink}
textStyles={[styles.textSupporting]}
/>
)}
</View>
<FixedFooter
style={[styles.mtAuto, styles.ph0]}
addBottomSafeAreaPadding
>
<Button
success
text={translate('common.done')}
onPress={() => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_DESKTOP_TRIGGER_FIRST_SYNC.getRoute(policyID))}
pressOnEnter
large
/>
</FixedFooter>
</View>
)}
</ContentWrapper>
{hasResultOfFetchingSetupLink ? children : <FullPageOfflineBlockingView addBottomSafeAreaPadding>{children}</FullPageOfflineBlockingView>}
</ScreenWrapper>
);
}
Expand Down
Loading