A Deep Dive into React's New <Activity> Component
Source: Dev.to
Introduction
Have you ever navigated away from a tab in your app, only to return and find your scroll position lost, your input fields cleared, or a loading spinner greeting you all over again?
Traditionally, React developers have handled “showing and hiding” UI by conditionally mounting or unmounting components:
{isShowingSidebar && <Sidebar />}
While effective, this approach destroys the component state every time it unmounts. In modern React (v19+), there is a better way. Enter the <Offscreen> component.
Formerly known as the “Offscreen” API during its experimental phase, <Offscreen> is a built‑in React component that allows you to hide and restore UI without losing its internal state or DOM nodes. Instead of removing elements from the tree, <Offscreen> keeps them “alive” in the background but visually hidden.
The Basic Syntax
import { Offscreen } from 'react';
import { useState } from 'react';
function App() {
const [isVisible, setIsVisible] = useState(true);
return (
<Offscreen mode={isVisible ? "visible" : "hidden"}>
{/* Your component tree */}
</Offscreen>
);
}
Preserving “Ephemeral” State
<Offscreen> doesn’t just keep the JavaScript state; it also preserves the DOM state.
- Form Drafts – If a user types into a form, switches tabs, and comes back, their text is still there.
- Scroll Position – No more manual “scroll restoration” logic—the browser naturally keeps the scroll position because the element was never removed.
Intelligent Pre‑rendering
<Offscreen mode="hidden">
{/* Heavy component that can be pre‑rendered */}
</Offscreen>
When a component is inside a hidden <Offscreen> boundary:
- React renders it at a lower priority, ensuring it doesn’t block the main thread.
- It can fetch data (if using Suspense‑enabled sources like
use). - Effects (
useEffect) are skipped until the component actually becomes visible.
Faster Initial Hydration
How does it differ from display: none?
While <Offscreen> does use display: none under the hood to hide elements, it adds several layers of “React Intelligence”:
- Effect Orchestration – When
mode="hidden", React destroys youruseEffectcleanups and only re‑runs them when the component becomes visible. This prevents background components from running timers or subscriptions that eat up resources. - Priority Management – Updates inside a hidden
<Offscreen>are deprioritized. React won’t let a background re‑render cause a frame drop in your foreground UI. - View Transitions – It integrates with the View Transition API, allowing for smooth animations when content enters or exits.
- Ref Behavior – Because the DOM nodes still exist, refs continue to point to the hidden elements.
- Text‑only Components – If a component returns only text (no wrapper element),
<Offscreen>won’t render anything when hidden because there is no DOM element to applydisplay: noneto. - Side Effects – Side effects that aren’t inside
useEffect(e.g., an auto‑playing<video>) might continue to run in the background. Ensure your components are “well‑behaved.”
When to Use <Offscreen>
The <Offscreen> component is a major step toward “Agentic” UI—where apps prepare content in the background and remember exactly where the user left off. If you’re building:
- Complex dashboards
- Multi‑tab interfaces
- Performance‑heavy web apps
it’s time to stop unmounting and start using <Offscreen>.
Are you planning to refactor your tabs to use <Offscreen>? Let me know in the comments!