useEffectEvent
and moreJust in time for React Conf, the React team rolled out their third major update of the year, React 19.2, which features long-awaited features like the Activity API and the useEffectEvent
Hook.
This release also introduces significant improvements across rendering performance, developer experience, and server-side rendering capabilities. So, whether you’ve been waiting to explore these features since their experimental phase or are simply curious about how they enhance React’s core functionality, you’re in the right place.
In this article, we’ll break down what’s new in React 19.2, take a deeper look at the useEffectEvent
Hook (and how it compares to useRef
), and highlight other notable enhancements and hidden gems included in this update.
The Activity API and the useEffectEvent
Hook are no doubt the highlights of this update. Both features have been experimental for a while, and during that period, they’ve steadily gained traction among developers.
As a quick TL;DR:
useEffectEvent
Hook: A Hook to separate event-like logic from reactive Effects. It creates callbacks that always see the latest props and state without causing the Effect to rerun when those values change.Let’s go into each in more detail:
Most of the buzz centers around the Activity API, which, at a high level, is a wrapper component that allows you to efficiently hide and restore the UI and internal state of its children. At a lower level, it’s an API that can hide a React subtree, unmount its effects while preserving its state, and continue rendering it with lower priority:
<Activity mode={isShowingSidebar ? "visible" : "hidden"}> <Sidebar /> </Activity>
To elaborate, let’s look at the code block above. It illustrates an Activity
boundary around a <SideBar />
component, which conditionally hides or displays the sidebar based on the isShowingSidebar
state.
Traditionally, we would use an approach similar to the one below:
{isShowingSidebar && ( <Sidebar /> )}
Both approaches achieve the same outcome, i.e, rendering a background activity (in this case, the <Sidebar/>
component).
But they do so in different ways. Instead of completely unmounting the Sidebar
component and destroying its internal state, as the latter approach would, the Activity API hides the component using the CSS display: none
property.
However, it still destroys the component’s effects to prevent unwanted background side effects and reduce performance overhead.
This way, React only has to hide the component visually, allowing it to preserve the component’s state. When the component becomes visible again, React will restore its previous state and re-create the destroyed effects. This makes it especially useful for scenarios like tabbed interfaces, modals, or background tasks where you need to maintain component state without keeping everything actively rendered.
Check out our article on how the Activity API works, or refer to the official React Docs.
useEffectEvent
HookuseEffectEvent
is a Hook that extracts non-reactive logic from effects into reusable functions called Effect Events. It allows you to create stable event handler functions within effects that always have access to the latest state and props, without needing to be included in the dependency array:
function Component() { const [count, setCount] = useState(0); const countEventHandler = useEffectEvent(() => { console.log(count); }); useEffect(() => { const interval = setInterval(() => { cointEventHandler(); }, 1000); return () => clearInterval(interval); }, []); return ( … ); }
In the example above, the countEventHandler
function will always log the latest count
value. This might seem unusual because the function isn’t listed as a dependency of the effect, yet it still receives fresh data.
Without a dependency array, you can rest assured that your components won’t trigger unnecessary side effects, since the effect runs only once while the event handlers continue to update. However, where useEffectEvent
truly shines is in scenarios where effect logic is mixed with reactive logic that re-renders on every prop or state change.
Beyond the two key highlights we covered earlier, the React 19.2 update introduces a range of practical features, particularly around SSR, performance tooling, and internal defaults, that aim to improve the developer experience and address real, day-to-day challenges.
A significant addition in React 19.2 is the new cacheSignal
API, which lets developers detect when a cached fetch call’s lifetime has expired. When using cache()
to deduplicate expensive asynchronous requests, cacheSignal
provides a cancellation signal that indicates when the React render lifecycle associated with that cached data has ended or been aborted.
This allows developers to clean up or abort side effects, such as fetch requests or long-running computations, when React no longer needs the cached data. As a result, it improves resource efficiency and prevents unnecessary work. For instance:
import { cache, cacheSignal } from 'react'; const dedupedFetch = cache(async (url) => { const response = await fetch(url, { signal: cacheSignal() }); return response.json(); });
In this example, the cache()
function wraps an asynchronous fetch call to automatically deduplicate identical requests during a render. If multiple components or server functions request the same resource (e.g., the same API endpoint), React will reuse the cached result instead of making redundant network calls.
Passing cacheSignal
to fetch()
means the request can be automatically canceled if React determines that its result is no longer needed.
Another significant addition in 19.2 is partial pre-rendering. This feature allows developers to pre-render static parts of the application ahead of time and serve them directly from a CDN, while deferring the rendering of dynamic or interactive components to be resumed later.
This splitting of pre-rendering and resuming helps optimize load times and improve user experience by quickly displaying deterministically rendered static content while loading interactive features asynchronously.
For example, with new APIs like prerender
and resume
, you can create a fast-loading shell of the app and then fill in dynamic data or interactive elements afterward:
const { prelude, postponed } = await prerender(<App />, { signal: controller.signal }); // Send prelude to CDN ... const resumeStream = await resume(<App />, postponed); // Continue streaming dynamic content to client
This approach reduces time-to-first-paint and allows smoother incremental hydration of React Server Components. This is important because partial pre-rendering can accelerate the delivery of critical content on initial page load, improving perceived performance and SEO outcomes.
Starting in 19.2, React will now batch reveals of server-rendered suspense boundaries before the first paint, so multiple fallbacks resolve together instead of peeling them in, one by one. This fixes a behavioral inconsistency bug where suspense boundaries would reveal differently when rendered on the client versus streamed from the server.
This batching also prepares for future support of <ViewTransition>
animations during SSR, which enables larger, smoother animation groups instead of a chain of staggered reveals. Importantly, React uses heuristics to maintain core web vitals. So if a page load nears a threshold (say 2.5 seconds for Largest Contentful Paint), React will stop batching and reveal content immediately to prevent harming performance metrics.
This update improves visual consistency, user experience, and animation fluidity in server-rendered React apps, which is critical for fast-loading modern web applications.
React 19.2 ships with [email protected]
, which now uses the flat config format by default and introduces new compiler-powered rules.
One of the key improvements is better linting support for the new useEffectEvent
Hook. The linter now correctly ignores useEffectEvent
functions in dependency arrays, preventing false warnings and encouraging accurate effect logic.
This update strengthens React’s static analysis capabilities, which help developers catch potential issues earlier in development. By aligning the lint rules with React’s latest Hook semantics, teams can write more predictable and maintainable effect code, reduce unnecessary re-renders, and improve overall code quality across projects.
You can learn more about these updates and configuration changes in the official React documentation.
As explained earlier, most of the excitement around the React 19.2 update centers on the Activity API and the useEffectEvent
Hook. These features have captured much of the attention, which might cause some of the smaller updates and improvements to go unnoticed, even though they offer significant value in specific use cases.
React 19.2 introduces Performance Tracks, a new feature integrated with Chrome DevTools that gives developers more insightful visibility into React app performance.
There are two primary tracks:
Scheduler track: This track shows what React is working on according to task priority. For example, it distinguishes blocking work for urgent user interactions from lower-priority transition updates inside startTransition
. It also reveals scheduling details like when work is blocked or waiting for paint. This helps developers understand how React manages and prioritizes rendering work.
Components track: This track displays detailed information about React components’ rendering and side effects. It marks events such as component mounts, updates, unmounts, and when rendering is blocked due to yielding. This track helps identify components that are slow or unnecessarily re-rendering.
useId
prefixThe default prefix for IDs generated by React’s useId
hook has changed in 19.2 from special characters (like :r:
or «r»
) to a simpler _r_
. This update was driven by the need to support new features like View Transitions that require IDs to comply with CSS view-transition-name
and XML 1.0 naming rules.
This change ensures that auto-generated IDs remain compatible across the full range of styling and animation scenarios, helping prevent subtle bugs and improving integration with emerging web platform APIs.
This update brings Web Streams API support to Node.js for streaming server-side rendering. This includes new APIs like renderToReadableStream
, prerender
, and the new resume
streaming mechanisms designed for Web Streams.
While Web Streams enable modern browser-compatible streaming patterns in Node environments, the React team recommends sticking to Node Streams API for speed and compression support, as Web Streams currently do not support these by default.
You can learn more about these updates and configuration changes in the official React documentation.
When you choose to upgrade to React 19.2 will largely depend on your specific needs. If you believe the new features and improvements in 19.2 will significantly impact your workflow or streamline your current setup, you can upgrade now and start experiencing these benefits firsthand by following the steps in the next section.
However, this may not be the case for larger or more complex projects, which require careful testing to ensure that none of the new changes introduce breaking issues.
That said, once edge cases are accounted for, the improvements in this release are particularly valuable for complex applications. The useEffectEvent
Hook improves maintainability in projects with intricate reactive dependencies, the Activity API and batched Suspense boundaries improve performance, and the new performance track offers deeper insight into profiling and optimization.
Updating your React projects to the latest version, React 19.2 in this case, is a straightforward process. Simply run the following command to update to the most recent version of React:
npm install react@latest react-dom@latest #or yarn add react@latest react-dom@latest
Alternatively, if newer versions have been released by the time you’re reading this, you can run the following command instead:
npm install [email protected] [email protected] # or yarn add [email protected] [email protected]
You should also consider upgrading the ESLint plugin to version 6.1.1 or higher to enable linting support for the new useEffectEvent
hook.
npm install eslint-plugin-react-hooks@^6.1.1 --save-dev # or yarn add eslint-plugin-react-hooks@^6.1.1 --dev
React 19.2 may be a minor release, but it certainly feels like a major one. The range of new features and improvements provides a modern toolkit that brings React apps closer to current web standards and evolving user experience expectations.
Whether you’re building complex SPAs, enterprise dashboards, or interactive content platforms, React 19.2 delivers practical and powerful primitives that streamline workflows, boost performance, and offer a glimpse into the high-quality updates we can expect from the React team moving forward.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowCompare the top AI development tools and models of September 2025. View updated rankings, feature breakdowns, and find the best fit for you.
React Hooks and SolidJS Signals solve reactivity differently. Learn how each manages state and updates, and when to choose one approach over the other.
Discover how the Chakra UI MCP server integrates AI into your editor, reducing context switching and accelerating development by fetching real-time documentation, component data, and code insights directly in-app.
fetch
callSkip the LangChain.js overhead: How to build a Retrieval-Augmented Generation (RAG) AI agent from scratch using just the native `fetch()` API.