Deep Dive: React Activity Component (Full Technical Article)
Read this as the “under-the-hood + advanced usage” layer.
Where Activity fits in React’s long-term vision
React is slowly moving from:
“Render everything immediately”
to
“Render intention-aware UIs”
Key primitives in this journey:
-
Suspense→ data readiness -
useTransition→ priority -
useDeferredValue→ lag tolerance -
Activity→ *intentional presence*
Activity answers a question React previously couldn’t:
“Is this UI logically present, but temporarily irrelevant?”
That distinction unlocks massive scheduling and performance gains.
Internal mental model (very important)
React internally tracks three dimensions for a tree:
- Mounted vs Unmounted
- Visible vs Hidden
- Active vs Inactive ← new
Before Activity, React only understood (1).
What Activity adds
Mounted ✅
Rendered ✅
DOM exists ✅
State exists ✅
Effects running ❌ (inactive)
Scheduler priority ❌
This is not just display: none.
What exactly is “paused” inside an inactive Activity?
Paused
useEffectuseLayoutEffect- Subscriptions (WebSocket, observers)
- Timers (
setInterval,setTimeout) - React state updates
- Context propagation
- Re-renders
NOT paused
- DOM nodes
- Layout
- State memory
- Ref values
- Suspense cache
This is why Activity is safe and predictable.
Lifecycle timeline example
<Activity mode="inactive">
<Component />
</Activity>
Timeline:
- Component mounts (once)
- Effects do not run
- Switch to
active - Effects run
- Switch back to
inactive - Cleanup runs
- No re-renders until reactivated
This is deterministic, not heuristic-based.
Activity vs Conditional Rendering (expanded)
Conditional rendering
{open && <Panel />}
Problems:
- Unmounts
- Loses state
- Re-fetches data
- Breaks transitions
Activity rendering
<Activity mode={open ? "active" : "inactive"}>
<Panel />
</Activity>
Benefits:
- Zero remount
- Zero data loss
- Predictable lifecycle
- CPU-friendly
Interaction with Concurrent Rendering
When a tree is inactive:
- React won’t schedule updates
- Updates are queued
- React coalesces state changes
- On activation → single render
This avoids:
- Update storms
- Background re-renders
- Invisible CPU drain
Activity + Server Components (future relevance)
While Activity itself is client-only, it complements React Server Components (RSC):
| Server | Client |
|---|---|
| Fetch once | Pause/resume |
| Cache data | Cache UI |
| Stream HTML | Freeze logic |
Together, they enable:
- Instant navigations
- Stateful UI reuse
- Minimal JS churn
Why Activity is safer than manual hacks
❌ CSS hiding
display: none;
- Effects still run
- Timers keep firing
- Network requests continue
❌ Custom “paused” flags
if (!active) return;
- Easy to forget
- Bugs everywhere
- Hard to scale
✅ Activity
- Centralized
- Declarative
- Scheduler-aware
- Tested by React core
Edge cases & gotchas (read carefully)
1. Controlled inputs
- Safe
- State preserved
- Cursor position preserved
2. Animations
- CSS animations continue
- JS-driven animations pause
- Recommended: pause animations manually on inactive
3. Event handlers
- Still attached
- But React won’t re-render from them
- Best practice: disable interaction visually
Activity + Context behavior
- Context does not propagate updates into inactive trees
- On reactivation → latest context value used
- Prevents cascading re-renders
This is huge for large apps.
Advanced pattern: Activity Stack
<Activity mode={step === 1 ? "active" : "inactive"}>
<StepOne />
</Activity>
<Activity mode={step === 2 ? "active" : "inactive"}>
<StepTwo />
</Activity>
Perfect for:
- Onboarding flows
- Wizards
- Checkout funnels
No state juggling needed.
Performance implications (real numbers conceptually)
In large dashboards:
- ❌ Hidden components = 30–40% wasted CPU
- ✅ Inactive Activity = near-zero CPU
This is why Meta built this.
How this relates to Meta / Instagram / Facebook UIs
Large Meta apps:
- Keep many screens mounted
- Switch instantly
- No data loss
- No jank
Activity is how that pattern becomes public React API.
Status recap (expanded)
- 🧪 Experimental
- 🚧 API stable conceptually
- 🔮 Minor naming changes possible
- 🧠 Mental model is final
Learn it now → future-proof React knowledge
Final takeaway (bookmark this)
Unmounting is destruction
Suspense is waiting
Activity is intentional pause
Once you understand this, modern React clicks differently.
Huge Shoutout
Top comments (0)