Navigation state persistence helps your app remember where you were last time you used it. This way, when you open the app again, it shows the same screen instead of starting over.
Navigation state persistence in React Native
import React from 'react'; import AsyncStorage from '@react-native-async-storage/async-storage'; import { NavigationContainer } from '@react-navigation/native'; const PERSISTENCE_KEY = 'NAVIGATION_STATE'; export default function App() { const [isReady, setIsReady] = React.useState(false); const [initialState, setInitialState] = React.useState(); React.useEffect(() => { const restoreState = async () => { try { const savedStateString = await AsyncStorage.getItem(PERSISTENCE_KEY); const state = savedStateString ? JSON.parse(savedStateString) : undefined; if (state) { setInitialState(state); } } finally { setIsReady(true); } }; if (!isReady) { restoreState(); } }, [isReady]); if (!isReady) { return null; // or a loading indicator } return ( <NavigationContainer initialState={initialState} onStateChange={(state) => AsyncStorage.setItem(PERSISTENCE_KEY, JSON.stringify(state)) } > {/* Your navigators here */} </NavigationContainer> ); }
Use AsyncStorage to save and load navigation state asynchronously.
Wrap your app in NavigationContainer and provide initialState and onStateChange props.
const PERSISTENCE_KEY = 'NAV_STATE';
// Save state
AsyncStorage.setItem(PERSISTENCE_KEY, JSON.stringify(state));const savedStateString = await AsyncStorage.getItem(PERSISTENCE_KEY);
const state = savedStateString ? JSON.parse(savedStateString) : undefined;<NavigationContainer
initialState={initialState}
onStateChange={state => AsyncStorage.setItem(PERSISTENCE_KEY, JSON.stringify(state))}
>This app has two screens: Home and Details. When you navigate between them, the app saves your place. If you close and reopen the app, it opens the screen you last visited.
import React from 'react'; import { View, Text, Button } from 'react-native'; import AsyncStorage from '@react-native-async-storage/async-storage'; import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; const Stack = createStackNavigator(); const PERSISTENCE_KEY = 'NAVIGATION_STATE'; function HomeScreen({ navigation }) { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Text>Home Screen</Text> <Button title="Go to Details" onPress={() => navigation.navigate('Details')} /> </View> ); } function DetailsScreen() { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Text>Details Screen</Text> </View> ); } export default function App() { const [isReady, setIsReady] = React.useState(false); const [initialState, setInitialState] = React.useState(); React.useEffect(() => { const restoreState = async () => { try { const savedStateString = await AsyncStorage.getItem(PERSISTENCE_KEY); const state = savedStateString ? JSON.parse(savedStateString) : undefined; if (state) { setInitialState(state); } } finally { setIsReady(true); } }; if (!isReady) { restoreState(); } }, [isReady]); if (!isReady) { return null; } return ( <NavigationContainer initialState={initialState} onStateChange={(state) => AsyncStorage.setItem(PERSISTENCE_KEY, JSON.stringify(state))} > <Stack.Navigator> <Stack.Screen name="Home" component={HomeScreen} /> <Stack.Screen name="Details" component={DetailsScreen} /> </Stack.Navigator> </NavigationContainer> ); }
Make sure to install @react-native-async-storage/async-storage to use AsyncStorage.
Saving state on every navigation change may affect performance on very large apps; consider throttling if needed.
Test on both Android and iOS devices as storage behavior can differ slightly.
Navigation state persistence saves where the user is in the app.
Use AsyncStorage to save and restore navigation state.
Wrap your app in NavigationContainer with initialState and onStateChange props.
Practice
Solution
Step 1: Understand navigation state persistence
Navigation state persistence means saving where the user is in the app so they can continue from the same place later.Step 2: Identify the correct purpose
Only To save the user's current screen so they return to it after closing the app describes saving the current screen to restore it after app restart.Final Answer:
To save the user's current screen so they return to it after closing the app -> Option CQuick Check:
Navigation state persistence = save current screen [OK]
- Confusing navigation state with app theme or cache
- Thinking it resets app screens instead of saving them
NavigationContainer for state persistence?Solution
Step 1: Recall NavigationContainer props for persistence
The correct props areinitialStateto set saved state andonStateChangeto save new state.Step 2: Match options with correct props
Only usesinitialStateandonStateChangecorrectly.Final Answer:
<NavigationContainer initialState={savedState} onStateChange={saveState}> -> Option DQuick Check:
Use initialState and onStateChange props [OK]
- Using wrong prop names like state or onChange
- Swapping savedState and saveState variables
const [initialState, setInitialState] = React.useState();
React.useEffect(() => {
AsyncStorage.getItem('NAV_STATE').then(state => {
if(state) setInitialState(JSON.parse(state));
});
}, []);
AsyncStorage.setItem('NAV_STATE', JSON.stringify(state))}
>
{/* screens */}
;Solution
Step 1: Understand AsyncStorage usage
The code loads saved navigation state from AsyncStorage and sets it as initialState.Step 2: Effect of initialState on NavigationContainer
Passing initialState restores the last screen, so the app opens on 'Profile' after restart.Final Answer:
The app opens on the 'Profile' screen automatically -> Option BQuick Check:
Saved state restores last screen [OK]
- Assuming app ignores saved state and resets
- Thinking missing state causes crash
const [navState, setNavState] = React.useState();
React.useEffect(() => {
AsyncStorage.getItem('NAV_STATE').then(state => {
setNavState(state);
});
}, []);
AsyncStorage.setItem('NAV_STATE', JSON.stringify(state))}
>
{/* screens */}
;Solution
Step 1: Check AsyncStorage.getItem usage
AsyncStorage.getItem returns a JSON string, so it must be parsed before use.Step 2: Identify missing JSON.parse
The code sets navState directly to the string, causing navigation to fail.Final Answer:
The saved state is not parsed from JSON before setting navState -> Option AQuick Check:
Parse JSON before setting state [OK]
- Forgetting JSON.parse on saved state
- Misusing onStateChange callback
Solution
Step 1: Understand conditional saving need
We want to save navigation state only after user navigates once, so we track navigation occurrence.Step 2: Use a ref to track navigation
A ref can store a boolean flag that updates on first navigation, then onStateChange saves state only if true.Step 3: Evaluate other options
Save state immediately on app start inside useEffect saves immediately, ignoring condition; C clears storage unnecessarily; D disables persistence.Final Answer:
Use a ref to track if navigation happened, then save state in onStateChange only if true -> Option AQuick Check:
Track navigation with ref before saving state [OK]
- Saving state too early before navigation
- Clearing storage unnecessarily
- Ignoring initialState updates
Ready to prove it?
Pass the test and this pattern moves unknown
