React 19.2 introduces a new component

If you’ve ever built a tab system, modal, or multi-step form, you’ve probably faced this dilemma:

  • Conditional rendering ({show && <Comp />}) destroys the component when hidden → you lose state.
  • Keeping everything mounted (<Comp style={{ display: 'none' }}>) preserves state, but effects and updates keep running in the background → wasted work.

The new <Activity /> component sits in between: it keeps state alive, but pauses effects and defers updates when hidden.

How <Activity /> Works

Think of <Activity /> as React’s pause button for components.

  • When mode="visible" (active):

    • Component runs normally
    • Effects execute (e.g. API calls, event listeners)
    • State updates trigger re-renders
    • DOM is visible
  • When mode="hidden" (paused):

    • Effects are cleaned up (no API calls, intervals, subscriptions)
    • State updates are remembered, but don’t trigger re-render immediately
    • DOM is hidden, but not destroyed
    • When made visible again → React flushes updates + resumes effects

Example 1: Tabs with Preserved State

Without <Activity /> (conditional rendering)

function App() {
  const [tab, setTab] = useState("home");

  return (
    <>
      <button onClick={() => setTab("home")}>Home</button>
      <button onClick={() => setTab("settings")}>Settings</button>

      {tab === "home" && <Home />}
      {tab === "settings" && <Settings />}
    </>
  );
}

👉 Problem: when you switch tabs, the inactive component is destroyed. If you typed something in “Settings”, it resets every time.

With <Activity />

function App() {
  const [tab, setTab] = useState("home");

  return (
    <>
      <button onClick={() => setTab("home")}>Home</button>
      <button onClick={() => setTab("settings")}>Settings</button>

      <Activity mode={tab === "home" ? "visible" : "hidden"}>
        <Home />
      </Activity>

      <Activity mode={tab === "settings" ? "visible" : "hidden"}>
        <Settings />
      </Activity>
    </>
  );
}

👉 Now:

  • Switching tabs is instant (state preserved).
  • Hidden tab doesn’t keep running effects.
  • State updates in hidden tab are stored → when visible, UI is up to date.

Example 2: Notifications Component

function Notifications() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log("🔔 Fetching notifications...");
    const id = setInterval(() => {
      setCount(c => c + 1);
    }, 2000);

    return () => clearInterval(id);
  }, []);

  return <p>You have {count} notifications.</p>;
}

function App() {
  const [open, setOpen] = useState(false);

  return (
    <>
      <button onClick={() => setOpen(o => !o)}>Toggle Notifications</button>

      <Activity mode={open ? "visible" : "hidden"}>
        <Notifications />
      </Activity>
    </>
  );
}
  • Visible → interval runs, fetching every 2s
  • Hidden → interval cleaned up (no fetch while hidden)
  • Re-open → notifications count resumes with latest state

Advantages

  • Preserves state (no reset on tab switch)
  • Preloads modules → user sees screen instantly when switching
  • Pauses background work → no wasted API calls or event listeners
  • Better UX → smooth transitions without heavy remounting

Disadvantages

  • Memory cost → components stay mounted in memory
  • Extra complexity if overused → e.g. keeping dozens of activities hidden may bloat memory

In Simple terms, you can think of it like: as minimizing an app:
Not visible, but memory and state are kept.
CPU work is paused until you “maximize” it again.

🚀 This is just one of the new features in React 19.2. In the next article of this series, we’ll explore useEffectEvent — a new hook that helps you avoid stale closures in event handlers.

👋 Hey, I’m Preethi!

I’m that frontend engineer who gets way too excited about pixel-perfect UIs, funky CSS tricks, and the newest React toys (yup, including React 19.2 ✨). When I’m not squashing bugs, I’m probably writing about them—or building design systems that behave better than my coffee machine ☕.

If you enjoyed this read, stick around—I’ve got more React 19.2 goodness coming your way. Let’s learn, laugh, and ship cool stuff together 🚀.

Similar Posts