React 19.2: In-Depth Guide with Code Examples
The New <Activity> Component: Pausing UI Sections Without Losing State#
Problem with Traditional Conditional Rendering#
Before React 19.2, hiding parts of UI was commonly done with conditional rendering:
{
isVisible && <Page />;
}While this unmounts the component and its state cleanly, it causes loss of any local state inside <Page>. Users often experience state resets, like losing typed input or scroll positions.
An alternative was keeping components mounted but hidden via CSS:
<div style={{ display: isVisible ? "block" : "none" }}>
<Page />
</div>This preserves the component and state, but React keeps running effects and updates in the background unnecessarily, wasting resources.
What Does <Activity> Solve?#
The new <Activity> component bridges the gap perfectly by letting you “pause” parts of your UI:
- When
mode="visible", children behave normally: effects run, state updates re-render, and DOM is visible. - When
mode="hidden", children remain mounted preserving their internal React state, effects and subscriptions are cleaned up (stopped), and re-renders are deferred or deprioritized. - React visually hides the content with
display: none. - When switching back to
visible, React restores effects and updates, keeping state intact.
This means UI parts can be hidden to save resources without losing their state, enabling faster navigations or tabs with non-destructive state preservation.
Syntax#
<Activity mode={isVisible ? "visible" : "hidden"}>
<YourComponent />
</Activity>The mode prop controls visibility with 'visible' or 'hidden', defaulting to 'visible'.
Example: Tab Interface Preserving State#
import { useState } from "react";
import { Activity } from "react";
function TabContent({ tabId }) {
const [input, setInput] = useState("");
return (
<div>
<h2>Tab {tabId}</h2>
<input
value={input}
onChange={e => setInput(e.target.value)}
placeholder="Type something"
/>
<p>You typed: {input}</p>
</div>
);
}
function Tabs() {
const [activeTab, setActiveTab] = useState(1);
return (
<>
<button onClick={() => setActiveTab(1)}>Tab 1</button>
<button onClick={() => setActiveTab(2)}>Tab 2</button>
<Activity mode={activeTab === 1 ? "visible" : "hidden"}>
<TabContent tabId={1} />
</Activity>
<Activity mode={activeTab === 2 ? "visible" : "hidden"}>
<TabContent tabId={2} />
</Activity>
</>
);
}Here, switching tabs hides inactive tab content visually and pauses its effects, but preserves typed input state and scroll position. This results in smooth UX without losing data.
useEffectEvent Hook: Stable Event Handlers Without Effect Re-Runs#
Why useEffectEvent?#
With React hooks, managing event handlers that depend on component props or state often causes effects to subscribe and unsubscribe repeatedly, leading to performance issues.
useEffect(() => {
function handleResize() {
console.log(size); *// size from props or state*
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, [size]);The above will re-run whenever size changes.
What useEffectEvent Does#
useEffectEvent isolates event handler logic from effect dependencies by creating a stable callback that always refers to the latest props/state without effect cleanup.
Usage Example#
import { useEffectEvent } from "react";
function ResizableComponent({ size }) {
const handleResize = useEffectEvent(() => {
console.log("Window resized, current size:", size);
});
useEffect(() => {
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, [handleResize]);
return <div>Size: {size}</div>;
}Here, handleResize callback always uses the latest size without needing to re-subscribe on every size update. This simplifies effect logic and boosts performance.
cache & cacheSignal for Efficient Data Fetching and Request Cancellation#
What Are They?#
React 19.2 introduces cache for memoizing async operations, avoiding redundant fetches, and cacheSignal to cancel in-flight requests when no longer needed, especially used in React Server Components.
Example: Caching a User Fetch#
import { cache } from "react";
const fetchUser = cache(async (id, { cacheSignal }) => {
const response = await fetch(`/api/users/${id}`, { signal: cacheSignal });
return await response.json();
});
function UserProfile({ userId }) {
const user = fetchUser(userId);
return <div>{user.name}</div>;
}If multiple requests for the same userId happen simultaneously, cache ensures only one fetch runs. If the request is aborted (e.g., user navigated away), cacheSignal cancels the fetch properly, saving bandwidth.
Partial Pre-rendering & Resume API for Speedy SSR#
React 19.2 supports splitting server-rendered content into static and dynamic parts:
- Pre-render stable UI shell ahead.
- Resume rendering interactive content asynchronously on client.
This approach reduces time-to-first-paint drastically and improves perceived performance on large apps.
Example Concept (Server Side):#
const { prelude, postponed } = await prerender(<App />);
sendToClient(prelude); *// static shell*
const resumeStream = await resume(<App />, postponed);
streamToClient(resumeStream); *// dynamic parts later*Other Notable Improvements#
- Enhanced React DevTools for better performance and scheduler visualization.
- Improved ESLint React Hooks plugin catching subtle bugs.
- SSR Optimizations with Suspense batching and Web Streams.
- Better integration with Web Components and Custom Elements.
Final Thoughts
React 19.2 significantly improves handling of UI visibility and state with the <Activity> component, allowing developers to hide UI parts without losing state or running unnecessary effects. useEffectEvent fixes common hook dependency problems by stabilizing event handlers. Efficient caching and cancellation with cache and cacheSignal, combined with partial SSR pre-rendering, boost app performance.
These features empower developers to write cleaner, faster React apps with smoother user experiences. Explore these APIs in your upcoming projects for better control and performance gains.
If you want, this blog can be adapted into a detailed YouTube tutorial script to help your audience learn these concepts visually. Just ask!
This detailed guide aims to serve as a one-stop reference for React 19.2 features, ensuring users understand the concepts and practical implementations clearly without needing external resources.
All information is based on official React 19.2 documentation and community insights from October 2025.
References:#
- https://react.dev/reference/react/Activity
- https://react.dev/blog/2025/10/01/react-19-2
- https://javascript.plainenglish.io/tried-react-19s-activity-component-here-s-what-i-learned-b0f714003a65
- https://dev.to/preethi_dev/react-192-introduces-a-new-component-10cp
- https://www.infoq.com/news/2025/10/meta-ships-react-19-2/
- https://www.reddit.com/r/react/comments/1nxcbv9/activity_in_react_192/
- https://www.linkedin.com/posts/eduardkramarenko_react19-javascript-frontend-activity-7389201874039504897-2FwM
- https://www.youtube.com/watch?v=d7FKiQmFfz8
- https://www.youtube.com/watch?v=KI4gjUrOfOs
- https://javascript-conference.com/blog/react-19-2-updates-performance-activity-component/