|
import AsyncStorage from '@react-native-community/async-storage'; |
|
import { |
|
InitialState, |
|
NavigationContainer, |
|
NavigationContainerProps, |
|
NavigationContainerRef, |
|
} from '@react-navigation/core'; |
|
import * as React from 'react'; |
|
import { InteractionManager } from 'react-native'; |
|
|
|
interface DevPersistedNavigationContainerProps |
|
extends NavigationContainerProps { |
|
persistKey: string; |
|
} |
|
|
|
const DevPersistedNavigationContainerImpl = React.forwardRef< |
|
NavigationContainerRef, |
|
DevPersistedNavigationContainerProps |
|
>(({ persistKey, onStateChange, ...others }, forwardedRef) => { |
|
const [isReady, setIsReady] = React.useState(false); |
|
const [initialState, setInitialState] = React.useState< |
|
InitialState | undefined |
|
>(); |
|
const persistInteractionRef = React.useRef<{ cancel: () => void } | null>( |
|
null, |
|
); |
|
const onStateChangeInternal = React.useCallback( |
|
state => { |
|
const persistState = async () => { |
|
persistInteractionRef.current = null; |
|
try { |
|
await AsyncStorage.setItem(persistKey, JSON.stringify(state)); |
|
} catch (ex) { |
|
// eslint-disable-next-line no-console |
|
console.warn('Failed to persist state. ' + ex.message); |
|
} |
|
}; |
|
|
|
if (persistInteractionRef.current !== null) { |
|
persistInteractionRef.current.cancel(); |
|
} |
|
|
|
if (state != null) { |
|
persistInteractionRef.current = InteractionManager.runAfterInteractions( |
|
persistState, |
|
); |
|
} |
|
|
|
if (onStateChange != null) { |
|
onStateChange(state); |
|
} |
|
}, |
|
[onStateChange, persistKey], |
|
); |
|
|
|
React.useEffect(() => { |
|
const loadPerisitedState = async () => { |
|
try { |
|
const jsonString = await AsyncStorage.getItem(persistKey); |
|
if (jsonString != null) { |
|
setInitialState(JSON.parse(jsonString)); |
|
} |
|
setIsReady(true); |
|
} catch (ex) { |
|
// eslint-disable-next-line no-console |
|
console.warn('Failed to load state. ' + ex.message); |
|
setIsReady(true); |
|
} |
|
}; |
|
loadPerisitedState(); |
|
}, [persistKey]); |
|
|
|
if (!isReady) { |
|
return null; |
|
} |
|
|
|
return ( |
|
<NavigationContainer |
|
{...others} |
|
ref={forwardedRef} |
|
initialState={initialState} |
|
onStateChange={onStateChangeInternal} |
|
/> |
|
); |
|
}); |
|
|
|
export const DevPersistedNavigationContainer = __DEV__ |
|
? DevPersistedNavigationContainerImpl |
|
: NavigationContainer; |