Why Screens Blur, Unmount, Reset — and How to Avoid Common Bugs
React Native looks a lot like React web, but the way screens behave when you navigate between them is fundamentally different.
Unlike the web, where components usually stay mounted as long as the route exists, React Native screens follow a navigation lifecycle and a mobile OS lifecycle.
This article explains:
- What really happens when you navigate between screens
- Why your screen may reset or reload unexpectedly
- A real bug example (scroll position + API reload issue)
- What Tab Navigator preserves — and what it doesn't
- Simple diagrams to make everything clear
🔁 1. What Is the Navigation Lifecycle?
When you navigate from one screen to another in React Native (via React Navigation), the previous screen may:
- stay mounted but lose focus
- fully unmount
- be killed later by the OS under memory pressure
Diagram:
[A] ---- navigate ----> [B]
Possible states for [A]:
1. blurred (still mounted)
2. unmounted (destroyed)
3. killed by OS (memory)
1️⃣ Screen: Focused
The screen is visible and interactive.
[Home] (focused)
2️⃣ Screen: Blurred (Still Mounted)
[Home] (blurred)
↓
[Details] (focused)
- State preserved
- UI paused
- Focus/blur events triggered
3️⃣ Screen: Unmounted
[Home] (❌ unmounted)
↓
[Details]
Screen remounts from scratch when user returns.
4️⃣ Screen: Killed by OS (low memory)
[Home] (background)
↓ OS low memory
App killed ❌
Reopening = full cold start.
🐞 2. Example Bug When Not Handling Unmounting
export default function HomeScreen() {
const [animals, setAnimals] = useState([]);
useEffect(() => {
loadAnimals();
}, []);
return (
<FlatList
data={animals}
renderItem={({ item }) => <Text>{item.name}</Text>}
/>
);
}
❌ Bug symptoms after unmount:
- List flashes empty
- API refetch
- Scroll position resets
- UI flickers
- Timers restart
🛠️ 3. How to Fix It
✔ Global store (React Query, Zustand)
const { data: animals } = useQuery(['animals'], loadAnimals);
✔ Refetch on focus
useFocusEffect(useCallback(() => {
loadAnimals();
}, []));
✔ Avoid unmountOnBlur when not necessary
✔ Persist scroll or UI state
📦 4. Tab Navigator Behavior
Tab Navigator keeps screens mounted:
[Tab A] (mounted)
[Tab B] (mounted)
Switch tabs → stays mounted
Good for dashboards, feeds, maps.
❗ OS Can Still Kill the App
Tab Navigator cannot prevent:
- iOS killing the app in background
- Android reclaiming memory
- JS thread termination
Diagram:
Tabs mounted
↓ Home button
App backgrounded
↓ Low memory
OS kills app ❌
Reopen → cold start.
🎯 Summary
React Native screens can:
- focus
- blur
- unmount
- remount
- be killed by OS
Understanding this prevents bugs:
- lost scroll
- API refetch loops
- screen flicker
- reset UI state
Tab Navigator keeps screens mounted during navigation —
but cannot stop the OS from killing your app under memory pressure.
Top comments (0)