DEV Community

Cathy Lai
Cathy Lai

Posted on

Understanding React Native Navigation Lifecycle

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:

  1. stay mounted but lose focus
  2. fully unmount
  3. 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)
Enter fullscreen mode Exit fullscreen mode

1️⃣ Screen: Focused

The screen is visible and interactive.

[Home] (focused)
Enter fullscreen mode Exit fullscreen mode

2️⃣ Screen: Blurred (Still Mounted)

[Home] (blurred)
      ↓
[Details] (focused)
Enter fullscreen mode Exit fullscreen mode
  • State preserved
  • UI paused
  • Focus/blur events triggered

3️⃣ Screen: Unmounted

[Home] (❌ unmounted)
      ↓
[Details]
Enter fullscreen mode Exit fullscreen mode

Screen remounts from scratch when user returns.


4️⃣ Screen: Killed by OS (low memory)

[Home] (background)
 ↓ OS low memory
App killed ❌
Enter fullscreen mode Exit fullscreen mode

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>}
    />
  );
}
Enter fullscreen mode Exit fullscreen mode

❌ 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);
Enter fullscreen mode Exit fullscreen mode

✔ Refetch on focus

useFocusEffect(useCallback(() => {
  loadAnimals();
}, []));
Enter fullscreen mode Exit fullscreen mode

✔ 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
Enter fullscreen mode Exit fullscreen mode

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 ❌
Enter fullscreen mode Exit fullscreen mode

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)