Skip to content

Instantly share code, notes, and snippets.

@janicduplessis
Created September 3, 2019 00:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save janicduplessis/689480d110a96ec2eada92443d466c61 to your computer and use it in GitHub Desktop.
Save janicduplessis/689480d110a96ec2eada92443d466c61 to your computer and use it in GitHub Desktop.
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;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment