Lazy Loading in React Navigation Stack: State Preservation Across Visits
0 reputation · 20 May 2023, 17:45 UTC
0 reputation · 20 May 2023, 17:45 UTC
The lazy option in React Navigation v6 defers rendering of screens until they are first focused. While the initial screen mounts immediately, subsequent screens only mount on first navigation.
When a user navigates away from a lazy‑loaded screen and then returns, developers often observe that the component remounts, resetting local state. However, the official documentation does not clarify whether state should be preserved across visits.
Platform‑specific rendering optimizations may influence this behavior, and future releases could alter the semantics of lazy. The community has not reached consensus on a consistent design decision.
What guarantees does React Navigation v6 provide for state persistence on lazy‑loaded screens when navigating back? Does the re‑mounting behavior differ reliably between iOS and Android? If state is not preserved, what best practices are recommended to maintain component data across visits?
React Navigation v6 guarantees that a screen is mounted only the first time it is focused when lazy is true. After that initial mount the component stays in the navigation stack; it is not unmounted when you navigate away. Consequently, all local state (e.g., useState, useRef, form values) survives a return to the screen unless you explicitly enable an unmount‑on‑blur option or use react-native-screens with unmountOnBlur set to true.
There is no documented platform‑specific difference between iOS and Android for this behavior. Both platforms use the same navigation stack implementation, so the life‑cycle is identical unless you toggle platform‑specific flags in react-native-screens or your own code.
unmountOnBlur or detachInactiveScreens can cause a remount.unmountOnBlur is not set to true in your navigator configuration.
createStackNavigator({
screenOptions: { unmountOnBlur: false },
});focus or blur listeners instead of useEffect with an empty dependency array.
useFocusEffect(
React.useCallback(() => {
// refresh data here
return () => {};
}, [])
);
useRef for mutable values that should not trigger re‑renders, or useState with a persisted key.react-native-screens, enable freezeOnBlur (default) to avoid unnecessary re‑renders while keeping the component mounted.Does your project have react-native-screens enabled and are you using its unmountOnBlur or detachInactiveScreens options? That detail can change whether a screen is remounted.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.