Skip to content

Commit 7f55e03

Browse files
Merge pull request #51725 from callstack-internal/fix/app-freeze-on-cache-clear
fix: App freeze when clearing cache
2 parents aedbbde + f326c30 commit 7f55e03

File tree

3 files changed

+29
-18
lines changed

3 files changed

+29
-18
lines changed

src/components/OptionListContextProvider.tsx

+25-17
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React, {createContext, useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react';
2-
import {withOnyx} from 'react-native-onyx';
3-
import type {OnyxCollection} from 'react-native-onyx';
2+
import {useOnyx} from 'react-native-onyx';
43
import usePrevious from '@hooks/usePrevious';
54
import * as OptionsListUtils from '@libs/OptionsListUtils';
65
import type {OptionList} from '@libs/OptionsListUtils';
@@ -17,14 +16,11 @@ type OptionsListContextProps = {
1716
initializeOptions: () => void;
1817
/** Flag to check if the options are initialized */
1918
areOptionsInitialized: boolean;
19+
/** Function to reset the options */
20+
resetOptions: () => void;
2021
};
2122

22-
type OptionsListProviderOnyxProps = {
23-
/** Collection of reports */
24-
reports: OnyxCollection<Report>;
25-
};
26-
27-
type OptionsListProviderProps = OptionsListProviderOnyxProps & {
23+
type OptionsListProviderProps = {
2824
/** Actual content wrapped by this component */
2925
children: React.ReactNode;
3026
};
@@ -36,6 +32,7 @@ const OptionsListContext = createContext<OptionsListContextProps>({
3632
},
3733
initializeOptions: () => {},
3834
areOptionsInitialized: false,
35+
resetOptions: () => {},
3936
});
4037

4138
const isEqualPersonalDetail = (prevPersonalDetail: PersonalDetails | null, personalDetail: PersonalDetails | null) =>
@@ -44,12 +41,13 @@ const isEqualPersonalDetail = (prevPersonalDetail: PersonalDetails | null, perso
4441
prevPersonalDetail?.login === personalDetail?.login &&
4542
prevPersonalDetail?.displayName === personalDetail?.displayName;
4643

47-
function OptionsListContextProvider({reports, children}: OptionsListProviderProps) {
44+
function OptionsListContextProvider({children}: OptionsListProviderProps) {
4845
const areOptionsInitialized = useRef(false);
4946
const [options, setOptions] = useState<OptionList>({
5047
reports: [],
5148
personalDetails: [],
5249
});
50+
const [reports] = useOnyx(ONYXKEYS.COLLECTION.REPORT);
5351

5452
const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT;
5553
const prevPersonalDetails = usePrevious(personalDetails);
@@ -144,9 +142,22 @@ function OptionsListContextProvider({reports, children}: OptionsListProviderProp
144142
areOptionsInitialized.current = true;
145143
}, [loadOptions]);
146144

145+
const resetOptions = useCallback(() => {
146+
if (!areOptionsInitialized.current) {
147+
return;
148+
}
149+
150+
areOptionsInitialized.current = false;
151+
setOptions({
152+
reports: [],
153+
personalDetails: [],
154+
});
155+
}, []);
156+
147157
return (
148-
// eslint-disable-next-line react-compiler/react-compiler
149-
<OptionsListContext.Provider value={useMemo(() => ({options, initializeOptions, areOptionsInitialized: areOptionsInitialized.current}), [options, initializeOptions])}>
158+
<OptionsListContext.Provider // eslint-disable-next-line react-compiler/react-compiler
159+
value={useMemo(() => ({options, initializeOptions, areOptionsInitialized: areOptionsInitialized.current, resetOptions}), [options, initializeOptions, resetOptions])}
160+
>
150161
{children}
151162
</OptionsListContext.Provider>
152163
);
@@ -157,7 +168,7 @@ const useOptionsListContext = () => useContext(OptionsListContext);
157168
// Hook to use the OptionsListContext with an initializer to load the options
158169
const useOptionsList = (options?: {shouldInitialize: boolean}) => {
159170
const {shouldInitialize = true} = options ?? {};
160-
const {initializeOptions, options: optionsList, areOptionsInitialized} = useOptionsListContext();
171+
const {initializeOptions, options: optionsList, areOptionsInitialized, resetOptions} = useOptionsListContext();
161172

162173
useEffect(() => {
163174
if (!shouldInitialize || areOptionsInitialized) {
@@ -171,13 +182,10 @@ const useOptionsList = (options?: {shouldInitialize: boolean}) => {
171182
initializeOptions,
172183
options: optionsList,
173184
areOptionsInitialized,
185+
resetOptions,
174186
};
175187
};
176188

177-
export default withOnyx<OptionsListProviderProps, OptionsListProviderOnyxProps>({
178-
reports: {
179-
key: ONYXKEYS.COLLECTION.REPORT,
180-
},
181-
})(OptionsListContextProvider);
189+
export default OptionsListContextProvider;
182190

183191
export {useOptionsListContext, useOptionsList, OptionsListContext};

src/pages/settings/Troubleshoot/TroubleshootPage.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import * as Illustrations from '@components/Icon/Illustrations';
1111
import ImportOnyxState from '@components/ImportOnyxState';
1212
import LottieAnimations from '@components/LottieAnimations';
1313
import MenuItemList from '@components/MenuItemList';
14+
import {useOptionsList} from '@components/OptionListContextProvider';
1415
import ScreenWrapper from '@components/ScreenWrapper';
1516
import ScrollView from '@components/ScrollView';
1617
import Section from '@components/Section';
@@ -51,6 +52,7 @@ function TroubleshootPage() {
5152
const [isLoading, setIsLoading] = useState(false);
5253
const [shouldStoreLogs] = useOnyx(ONYXKEYS.SHOULD_STORE_LOGS);
5354
const [shouldMaskOnyxState = true] = useOnyx(ONYXKEYS.SHOULD_MASK_ONYX_STATE);
55+
const {resetOptions} = useOptionsList({shouldInitialize: false});
5456

5557
const exportOnyxState = useCallback(() => {
5658
ExportOnyxState.readFromOnyxDatabase().then((value: Record<string, unknown>) => {
@@ -160,6 +162,7 @@ function TroubleshootPage() {
160162
isVisible={isConfirmationModalVisible}
161163
onConfirm={() => {
162164
setIsConfirmationModalVisible(false);
165+
resetOptions();
163166
clearOnyxAndResetApp();
164167
}}
165168
onCancel={() => setIsConfirmationModalVisible(false)}

tests/perf-test/SearchRouter.perf-test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ function SearchRouterInputWrapper() {
143143
function SearchRouterWrapperWithCachedOptions() {
144144
return (
145145
<ComposeProviders components={[OnyxProvider, LocaleContextProvider]}>
146-
<OptionsListContext.Provider value={useMemo(() => ({options: mockedOptions, initializeOptions: () => {}, areOptionsInitialized: true}), [])}>
146+
<OptionsListContext.Provider value={useMemo(() => ({options: mockedOptions, initializeOptions: () => {}, resetOptions: () => {}, areOptionsInitialized: true}), [])}>
147147
<SearchRouter onRouterClose={mockOnClose} />
148148
</OptionsListContext.Provider>
149149
</ComposeProviders>

0 commit comments

Comments
 (0)