{"id":7786,"date":"2025-10-02T01:49:33","date_gmt":"2025-10-02T01:49:33","guid":{"rendered":"https:\/\/pokecon.jp\/job\/?p=7786"},"modified":"2025-10-02T01:49:33","modified_gmt":"2025-10-02T01:49:33","slug":"react-19-2-react","status":"publish","type":"post","link":"https:\/\/pokecon.jp\/job\/7786\/","title":{"rendered":"React 19.2 \u2013 React"},"content":{"rendered":"\n<\/p>\n<div>\n<p class=\"whitespace-pre-wrap my-4\">October 1, 2025 by <a target=\"_blank\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\" href=\"https:\/\/react.dev\/community\/team\">The React Team<\/a><\/p>\n<hr class=\"my-6 block border-b border-t-0 border-border dark:border-border-dark\"\/>\n<div class=\"font-display text-xl text-primary dark:text-primary-dark leading-relaxed\">\n<p class=\"whitespace-pre-wrap my-4\">React 19.2 is now available on npm!<\/p>\n<\/div>\n<p class=\"whitespace-pre-wrap my-4\">This is our third release in the last year, following React 19 in December and React 19.1 in June. In this post, we\u2019ll give an overview of the new features in React 19.2, and highlight some notable changes.<\/p>\n<hr class=\"my-6 block border-b border-t-0 border-border dark:border-border-dark\"\/>\n<h2 id=\"new-react-features\" class=\"mdx-heading text-3xl font-display leading-10 text-primary dark:text-primary-dark font-bold my-6\">New React Features <\/h2>\n<h3 id=\"activity\" class=\"mdx-heading text-2xl font-display leading-9 text-primary dark:text-primary-dark font-bold my-6\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\"><activity\/><\/code> <\/h3>\n<p class=\"whitespace-pre-wrap my-4\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\"><activity\/><\/code> lets you break your app into \u201cactivities\u201d that can be controlled and prioritized.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">You can use Activity as an alternative to conditionally rendering parts of your app:<\/p>\n<p><!--$--><\/p>\n<div dir=\"ltr\" class=\"sandpack sandpack--codeblock rounded-2xl h-full w-full overflow-x-auto flex items-center bg-wash dark:bg-gray-95 shadow-lg my-8\" style=\"contain:content\">\n<div class=\"sp-wrapper\">\n<div class=\"sp-stack\">\n<div class=\"sp-code-editor\">\n<pre class=\"sp-cm sp-pristine sp-javascript flex align-start\"><code class=\"sp-pre-placeholder grow-[2]\"><p><span class=\"sp-syntax-punctuation\">{<\/span><span class=\"sp-syntax-plain\">isVisible<\/span> &amp;&amp; <span class=\"sp-syntax-punctuation\"><span class=\"sp-syntax-definition\">Page<\/span> <span class=\"sp-syntax-punctuation\">\/&gt;<\/span><span class=\"sp-syntax-punctuation\">}<\/span><br\/><\/span><\/p><p><span class=\"sp-syntax-punctuation\"><span class=\"sp-syntax-definition\">Activity<\/span> <span class=\"sp-syntax-property\">mode<\/span>=<span class=\"sp-syntax-punctuation\">{<\/span><span class=\"sp-syntax-plain\">isVisible<\/span> ? <span class=\"sp-syntax-string\">'visible'<\/span> : <span class=\"sp-syntax-string\">'hidden'<\/span><span class=\"sp-syntax-punctuation\">}<\/span><span class=\"sp-syntax-punctuation\">&gt;<\/span><br\/><\/span><\/p><p>  <span class=\"sp-syntax-punctuation\"><span class=\"sp-syntax-definition\">Page<\/span> <span class=\"sp-syntax-punctuation\">\/&gt;<\/span><br\/><\/span><\/p><p><span class=\"sp-syntax-punctuation\"\/><span class=\"sp-syntax-definition\">Activity<\/span><span class=\"sp-syntax-punctuation\">&gt;<\/span><\/p><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><!--\/$--><\/p>\n<p class=\"whitespace-pre-wrap my-4\">In React 19.2, Activity supports two modes: <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">visible<\/code> and <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">hidden<\/code>.<\/p>\n<ul class=\"ms-6 my-3 list-disc\">\n<li class=\"leading-relaxed mb-1\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">hidden<\/code>: hides the children, unmounts effects, and defers all updates until React has nothing left to work on.<\/li>\n<li class=\"leading-relaxed mb-1\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">visible<\/code>: shows the children, mounts effects, and allows updates to be processed normally.<\/li>\n<\/ul>\n<p class=\"whitespace-pre-wrap my-4\">This means you can pre-render and keep rendering hidden parts of the app without impacting the performance of anything visible on screen.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">You can use Activity to render hidden parts of the app that a user is likely to navigate to next, or to save the state of parts the user navigates away from. This helps make navigations quicker by loading data, css, and images in the background, and allows back navigations to maintain state such as input fields.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">In the future, we plan to add more modes to Activity for different use cases.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">For examples on how to use Activity, check out the <a target=\"_blank\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\" href=\"https:\/\/react.dev\/reference\/react\/Activity\">Activity docs<\/a>.<\/p>\n<hr class=\"my-6 block border-b border-t-0 border-border dark:border-border-dark\"\/>\n<h3 id=\"use-effect-event\" class=\"mdx-heading text-2xl font-display leading-9 text-primary dark:text-primary-dark font-bold my-6\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">useEffectEvent<\/code> <\/h3>\n<p class=\"whitespace-pre-wrap my-4\">One common pattern with <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">useEffect<\/code> is to notify the app code about some kind of \u201cevents\u201d from an external system. For example, when a chat room gets connected, you might want to display a notification:<\/p>\n<p><!--$--><\/p>\n<div dir=\"ltr\" class=\"sandpack sandpack--codeblock rounded-2xl h-full w-full overflow-x-auto flex items-center bg-wash dark:bg-gray-95 shadow-lg my-8\" style=\"contain:content\">\n<div class=\"sp-wrapper\">\n<div class=\"sp-stack\">\n<div class=\"sp-code-editor\">\n<pre class=\"sp-cm sp-pristine sp-javascript flex align-start\"><code class=\"sp-pre-placeholder grow-[2]\"><p><span class=\"sp-syntax-keyword\">function<\/span> <span class=\"sp-syntax-definition\">ChatRoom<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">{<\/span> <span class=\"sp-syntax-property\">roomId<\/span><span class=\"sp-syntax-punctuation\">,<\/span> <span class=\"sp-syntax-property\">theme<\/span> <span class=\"sp-syntax-punctuation\">}<\/span><span class=\"sp-syntax-punctuation\">)<\/span> <span class=\"sp-syntax-punctuation\">{<\/span><br\/><\/p><p>  <span class=\"sp-syntax-definition\">useEffect<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">)<\/span> <span class=\"sp-syntax-punctuation\">=&gt;<\/span> <span class=\"sp-syntax-punctuation\">{<\/span><br\/><\/p><p>    <span class=\"sp-syntax-keyword\">const<\/span> <span class=\"sp-syntax-plain\">connection<\/span> = <span class=\"sp-syntax-definition\">createConnection<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-plain\">serverUrl<\/span><span class=\"sp-syntax-punctuation\">,<\/span> <span class=\"sp-syntax-plain\">roomId<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p>    <span class=\"sp-syntax-plain\">connection<\/span>.<span class=\"sp-syntax-property\">on<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-string\">'connected'<\/span><span class=\"sp-syntax-punctuation\">,<\/span> <span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">)<\/span> <span class=\"sp-syntax-punctuation\">=&gt;<\/span> <span class=\"sp-syntax-punctuation\">{<\/span><br\/><\/p><p>      <span class=\"sp-syntax-definition\">showNotification<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-string\">'Connected!'<\/span><span class=\"sp-syntax-punctuation\">,<\/span> <span class=\"sp-syntax-plain\">theme<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p>    <span class=\"sp-syntax-punctuation\">}<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p>    <span class=\"sp-syntax-plain\">connection<\/span>.<span class=\"sp-syntax-property\">connect<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p>    <span class=\"sp-syntax-keyword\">return<\/span> <span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">)<\/span> <span class=\"sp-syntax-punctuation\">=&gt;<\/span> <span class=\"sp-syntax-punctuation\">{<\/span><br\/><\/p><p>      <span class=\"sp-syntax-plain\">connection<\/span>.<span class=\"sp-syntax-property\">disconnect<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">)<\/span><br\/><\/p><p>    <span class=\"sp-syntax-punctuation\">}<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p>  <span class=\"sp-syntax-punctuation\">}<\/span><span class=\"sp-syntax-punctuation\">,<\/span> <span class=\"sp-syntax-punctuation\">[<\/span><span class=\"sp-syntax-plain\">roomId<\/span><span class=\"sp-syntax-punctuation\">,<\/span> <span class=\"sp-syntax-plain\">theme<\/span><span class=\"sp-syntax-punctuation\">]<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><!--\/$--><\/p>\n<p class=\"whitespace-pre-wrap my-4\">The problem with the code above is that a change to any values used inside such an \u201cevent\u201d will cause the surrounding Effect to re-run. For example, changing the <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">theme<\/code> will cause the chat room to reconnect. This makes sense for values related to the Effect logic itself, like <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">roomId<\/code>, but it doesn\u2019t make sense for <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">theme<\/code>.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">To solve this, most users just disable the lint rule and exclude the dependency. But that can lead to bugs since the linter can no longer help you keep the dependencies up to date if you need to update the Effect later.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">With <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">useEffectEvent<\/code>, you can split the \u201cevent\u201d part of this logic out of the Effect that emits it:<\/p>\n<p><!--$--><\/p>\n<div dir=\"ltr\" class=\"sandpack sandpack--codeblock rounded-2xl h-full w-full overflow-x-auto flex items-center bg-wash dark:bg-gray-95 shadow-lg my-8\" style=\"contain:content\">\n<div class=\"sp-wrapper\">\n<div class=\"sp-stack\">\n<div class=\"sp-code-editor\">\n<pre class=\"sp-cm sp-pristine sp-javascript flex align-start\"><code class=\"sp-pre-placeholder grow-[2]\"><p><span class=\"sp-syntax-keyword\">function<\/span> <span class=\"sp-syntax-definition\">ChatRoom<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">{<\/span> <span class=\"sp-syntax-property\">roomId<\/span><span class=\"sp-syntax-punctuation\">,<\/span> <span class=\"sp-syntax-property\">theme<\/span> <span class=\"sp-syntax-punctuation\">}<\/span><span class=\"sp-syntax-punctuation\">)<\/span> <span class=\"sp-syntax-punctuation\">{<\/span><br\/><\/p><p>  <span class=\"sp-syntax-keyword\">const<\/span> <span class=\"sp-syntax-plain\">onConnected<\/span> = <span class=\"sp-syntax-definition\">useEffectEvent<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">)<\/span> <span class=\"sp-syntax-punctuation\">=&gt;<\/span> <span class=\"sp-syntax-punctuation\">{<\/span><br\/><\/p><p>    <span class=\"sp-syntax-definition\">showNotification<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-string\">'Connected!'<\/span><span class=\"sp-syntax-punctuation\">,<\/span> <span class=\"sp-syntax-plain\">theme<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p>  <span class=\"sp-syntax-punctuation\">}<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p>  <span class=\"sp-syntax-definition\">useEffect<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">)<\/span> <span class=\"sp-syntax-punctuation\">=&gt;<\/span> <span class=\"sp-syntax-punctuation\">{<\/span><br\/><\/p><p>    <span class=\"sp-syntax-keyword\">const<\/span> <span class=\"sp-syntax-plain\">connection<\/span> = <span class=\"sp-syntax-definition\">createConnection<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-plain\">serverUrl<\/span><span class=\"sp-syntax-punctuation\">,<\/span> <span class=\"sp-syntax-plain\">roomId<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p>    <span class=\"sp-syntax-plain\">connection<\/span>.<span class=\"sp-syntax-property\">on<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-string\">'connected'<\/span><span class=\"sp-syntax-punctuation\">,<\/span> <span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">)<\/span> <span class=\"sp-syntax-punctuation\">=&gt;<\/span> <span class=\"sp-syntax-punctuation\">{<\/span><br\/><\/p><p>      <span class=\"sp-syntax-definition\">onConnected<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p>    <span class=\"sp-syntax-punctuation\">}<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p>    <span class=\"sp-syntax-plain\">connection<\/span>.<span class=\"sp-syntax-property\">connect<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p>    <span class=\"sp-syntax-keyword\">return<\/span> <span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">)<\/span> <span class=\"sp-syntax-punctuation\">=&gt;<\/span> <span class=\"sp-syntax-plain\">connection<\/span>.<span class=\"sp-syntax-property\">disconnect<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p>  <span class=\"sp-syntax-punctuation\">}<\/span><span class=\"sp-syntax-punctuation\">,<\/span> <span class=\"sp-syntax-punctuation\">[<\/span><span class=\"sp-syntax-plain\">roomId<\/span><span class=\"sp-syntax-punctuation\">]<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span> <br\/><\/p><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><!--\/$--><\/p>\n<p class=\"whitespace-pre-wrap my-4\">Similar to DOM events, Effect Events always \u201csee\u201d the latest props and state.<\/p>\n<p class=\"whitespace-pre-wrap my-4\"><strong class=\"font-bold\">Effect Events should <em>not<\/em> be declared in the dependency array<\/strong>. You\u2019ll need to upgrade to <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">eslint-plugin-react-hooks@6.1.0<\/code> so that the linter doesn\u2019t try to insert them as dependencies. Note that Effect Events can only be declared in the same component or Hook as \u201ctheir\u201d Effect. These restrictions are verified by the linter.<\/p>\n<div class=\"expandable-callout pt-8 pb-4 px-5 sm:px-8 my-8 relative rounded-none shadow-inner-border -mx-5 sm:mx-auto sm:rounded-2xl bg-green-5 dark:bg-green-60 dark:bg-opacity-20 text-primary dark:text-primary-dark text-lg\">\n<h3 class=\"text-2xl font-display font-bold text-green-60 dark:text-green-40\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"inline me-2 mb-1 text-lg text-green-60 dark:text-green-40\" width=\"2em\" height=\"2em\" viewbox=\"0 0 72 72\" fill=\"none\"><g clip-path=\"url(#clip0_40_48064)\"><path d=\"M24 27C24 25.3431 25.3431 24 27 24H45C46.6569 24 48 25.3431 48 27C48 28.6569 46.6569 30 45 30H27C25.3431 30 24 28.6569 24 27Z\" fill=\"currentColor\"\/><path d=\"M24 39C24 37.3431 25.3431 36 27 36H39C40.6569 36 42 37.3431 42 39C42 40.6569 40.6569 42 39 42H27C25.3431 42 24 40.6569 24 39Z\" fill=\"currentColor\"\/><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M12 18C12 13.0294 16.0294 9 21 9H51C55.9706 9 60 13.0294 60 18V54C60 58.9706 55.9706 63 51 63H21C16.0294 63 12 58.9706 12 54V18ZM21 15H51C52.6569 15 54 16.3431 54 18V54C54 55.6569 52.6569 57 51 57H21C19.3431 57 18 55.6569 18 54V18C18 16.3431 19.3431 15 21 15Z\" fill=\"currentColor\"\/><\/g><defs><clippath id=\"clip0_40_48064\"><rect width=\"72\" height=\"72\" fill=\"white\"\/><\/clippath><\/defs><\/svg>Note<\/h3>\n<div class=\"relative\">\n<div class=\"py-2\">\n<h4 id=\"when-to-use-useeffectevent\" class=\"mdx-heading text-xl font-display font-bold leading-9 my-4\">When to use <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">useEffectEvent<\/code> <\/h4>\n<p class=\"whitespace-pre-wrap my-4\">You should use <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">useEffectEvent<\/code> for functions that are conceptually \u201cevents\u201d that happen to be fired from an Effect instead of a user event (that\u2019s what makes it an \u201cEffect Event\u201d). You don\u2019t need to wrap everything in <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">useEffectEvent<\/code>, or to use it just to silence the lint error, as this can lead to bugs.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">For a deep dive on how to think about Event Effects, see: <a target=\"_blank\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\" href=\"http:\/\/react.dev\/learn\/separating-events-from-effects#extracting-non-reactive-logic-out-of-effects\">Separating Events from Effects<\/a>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<hr class=\"my-6 block border-b border-t-0 border-border dark:border-border-dark\"\/>\n<h3 id=\"cache-signal\" class=\"mdx-heading text-2xl font-display leading-9 text-primary dark:text-primary-dark font-bold my-6\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">cacheSignal<\/code> <\/h3>\n<p class=\"whitespace-pre-wrap my-4\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">cacheSignal<\/code> allows you to know when the <a target=\"_blank\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\" href=\"https:\/\/react.dev\/reference\/react\/cache\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">cache()<\/code><\/a> lifetime is over:<\/p>\n<p><!--$--><\/p>\n<div dir=\"ltr\" class=\"sandpack sandpack--codeblock rounded-2xl h-full w-full overflow-x-auto flex items-center bg-wash dark:bg-gray-95 shadow-lg my-8\" style=\"contain:content\">\n<div class=\"sp-wrapper\">\n<div class=\"sp-stack\">\n<div class=\"sp-code-editor\">\n<pre class=\"sp-cm sp-pristine sp-javascript flex align-start\"><code class=\"sp-pre-placeholder grow-[2]\"><p><span class=\"sp-syntax-keyword\">import<\/span> <span class=\"sp-syntax-punctuation\">{<\/span><span class=\"sp-syntax-plain\">cache<\/span><span class=\"sp-syntax-punctuation\">,<\/span> <span class=\"sp-syntax-plain\">cacheSignal<\/span><span class=\"sp-syntax-punctuation\">}<\/span> <span class=\"sp-syntax-keyword\">from<\/span> <span class=\"sp-syntax-string\">'react'<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p><span class=\"sp-syntax-keyword\">const<\/span> <span class=\"sp-syntax-plain\">dedupedFetch<\/span> = <span class=\"sp-syntax-definition\">cache<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-plain\">fetch<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p><span class=\"sp-syntax-keyword\">async<\/span> <span class=\"sp-syntax-keyword\">function<\/span> <span class=\"sp-syntax-definition\">Component<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">)<\/span> <span class=\"sp-syntax-punctuation\">{<\/span><br\/><\/p><p>  <span class=\"sp-syntax-keyword\">await<\/span> <span class=\"sp-syntax-definition\">dedupedFetch<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-plain\">url<\/span><span class=\"sp-syntax-punctuation\">,<\/span> <span class=\"sp-syntax-punctuation\">{<\/span> <span class=\"sp-syntax-property\">signal<\/span><span class=\"sp-syntax-punctuation\">:<\/span> <span class=\"sp-syntax-definition\">cacheSignal<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\">)<\/span> <span class=\"sp-syntax-punctuation\">}<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p><span class=\"sp-syntax-punctuation\">}<\/span><\/p><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><!--\/$--><\/p>\n<p class=\"whitespace-pre-wrap my-4\">This allows you to clean up or abort work when the result will no longer be used in the cache, such as:<\/p>\n<ul class=\"ms-6 my-3 list-disc\">\n<li class=\"leading-relaxed mb-1\">React has successfully completed rendering<\/li>\n<li class=\"leading-relaxed mb-1\">The render was aborted<\/li>\n<li class=\"leading-relaxed mb-1\">The render has failed<\/li>\n<\/ul>\n<p class=\"whitespace-pre-wrap my-4\">For more info, see the <a target=\"_blank\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\" href=\"https:\/\/react.dev\/reference\/react\/cacheSignal\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">cacheSignal<\/code> docs<\/a>.<\/p>\n<hr class=\"my-6 block border-b border-t-0 border-border dark:border-border-dark\"\/>\n<h3 id=\"performance-tracks\" class=\"mdx-heading text-2xl font-display leading-9 text-primary dark:text-primary-dark font-bold my-6\">Performance Tracks <\/h3>\n<p class=\"whitespace-pre-wrap my-4\">React 19.2 adds a new set of <a target=\"_blank\" href=\"https:\/\/developer.chrome.com\/docs\/devtools\/performance\/extension\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">custom tracks<\/a> to Chrome DevTools performance profiles to provide more information about the performance of your React app:<\/p>\n<div style=\"display:flex;justify-content:center;margin-bottom:1rem\"><picture><source srcset=\"https:\/\/react.dev\/images\/blog\/react-labs-april-2025\/perf_tracks.png\"\/><img decoding=\"async\" class=\"w-full light-image\" src=\"https:\/\/react.dev\/images\/blog\/react-labs-april-2025\/perf_tracks.webp\"\/><\/picture><picture><source srcset=\"https:\/\/react.dev\/images\/blog\/react-labs-april-2025\/perf_tracks_dark.png\"\/><img decoding=\"async\" class=\"w-full dark-image\" src=\"https:\/\/react.dev\/images\/blog\/react-labs-april-2025\/perf_tracks_dark.webp\"\/><\/picture><\/div>\n<p class=\"whitespace-pre-wrap my-4\">The <a target=\"_blank\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\" href=\"https:\/\/react.dev\/reference\/dev-tools\/react-performance-tracks\">React Performance Tracks docs<\/a> explain everything included in the tracks, but here is a high-level overview.<\/p>\n<h4 id=\"scheduler-\" class=\"mdx-heading text-xl font-display font-bold leading-9 my-4\">Scheduler \u269b <\/h4>\n<p class=\"whitespace-pre-wrap my-4\">The Scheduler track shows what React is working on for different priorities such as \u201cblocking\u201d for user interactions, or \u201ctransition\u201d for updates inside startTransition. Inside each track, you will see the type of work being performed such as the event that scheduled an update, and when the render for that update happened.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">We also show information such as when an update is blocked waiting for a different priority, or when React is waiting for paint before continuing. The Scheduler track helps you understand how React splits your code into different priorities, and the order it completed the work.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">See the <a target=\"_blank\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\" href=\"http:\/\/react.dev\/reference\/dev-tools\/react-performance-tracks#scheduler\">Scheduler track<\/a> docs to see everything included.<\/p>\n<h4 id=\"components-\" class=\"mdx-heading text-xl font-display font-bold leading-9 my-4\">Components \u269b <\/h4>\n<p class=\"whitespace-pre-wrap my-4\">The Components track shows the tree of components that React is working on either to render or run effects. Inside you\u2019ll see labels such as \u201cMount\u201d for when children mount or effects are mounted, or \u201cBlocked\u201d for when rendering is blocked due to yielding to work outside React.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">The Component track helps you understand when components are rendered or run effects, and the time it takes to complete that work to help identify performance problems.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">See the <a target=\"_blank\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\" href=\"http:\/\/react.dev\/reference\/dev-tools\/react-performance-tracks#components\">Component track docs<\/a> for see everything included.<\/p>\n<hr class=\"my-6 block border-b border-t-0 border-border dark:border-border-dark\"\/>\n<h2 id=\"new-react-dom-features\" class=\"mdx-heading text-3xl font-display leading-10 text-primary dark:text-primary-dark font-bold my-6\">New React DOM Features <\/h2>\n<h3 id=\"partial-pre-rendering\" class=\"mdx-heading text-2xl font-display leading-9 text-primary dark:text-primary-dark font-bold my-6\">Partial Pre-rendering <\/h3>\n<p class=\"whitespace-pre-wrap my-4\">In 19.2 we\u2019re adding a new capability to pre-render part of the app ahead of time, and resume rendering it later.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">This feature is called \u201cPartial Pre-rendering\u201d, and allows you to pre-render the static parts of your app and serve it from a CDN, and then resume rendering the shell to fill it in with dynamic content later.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">To pre-render an app to resume later, first call <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">prerender<\/code> with an <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">AbortController<\/code>:<\/p>\n<p><!--$--><\/p>\n<div dir=\"ltr\" class=\"sandpack sandpack--codeblock rounded-2xl h-full w-full overflow-x-auto flex items-center bg-wash dark:bg-gray-95 shadow-lg my-8\" style=\"contain:content\">\n<div class=\"sp-wrapper\">\n<div class=\"sp-stack\">\n<div class=\"sp-code-editor\">\n<pre class=\"sp-cm sp-pristine sp-javascript flex align-start\"><code class=\"sp-pre-placeholder grow-[2]\"><p><span class=\"sp-syntax-keyword\">const<\/span> <span class=\"sp-syntax-punctuation\">{<\/span><span class=\"sp-syntax-property\">prelude<\/span><span class=\"sp-syntax-punctuation\">,<\/span> <span class=\"sp-syntax-property\">postponed<\/span><span class=\"sp-syntax-punctuation\">}<\/span> = <span class=\"sp-syntax-keyword\">await<\/span> <span class=\"sp-syntax-definition\">prerender<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\"><span class=\"sp-syntax-definition\">App<\/span> <span class=\"sp-syntax-punctuation\">\/&gt;<\/span><span class=\"sp-syntax-punctuation\">,<\/span> <span class=\"sp-syntax-punctuation\">{<\/span><br\/><\/span><\/p><p>  <span class=\"sp-syntax-property\">signal<\/span><span class=\"sp-syntax-punctuation\">:<\/span> <span class=\"sp-syntax-plain\">controller<\/span>.<span class=\"sp-syntax-property\">signal<\/span><span class=\"sp-syntax-punctuation\">,<\/span><br\/><\/p><p><span class=\"sp-syntax-punctuation\">}<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p><span class=\"sp-syntax-keyword\">await<\/span> <span class=\"sp-syntax-definition\">savePostponedState<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-plain\">postponed<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><!--\/$--><\/p>\n<p class=\"whitespace-pre-wrap my-4\">Then, you can return the <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">prelude<\/code> shell to the client, and later call <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">resume<\/code> to \u201cresume\u201d to a SSR stream:<\/p>\n<p><!--$--><\/p>\n<div dir=\"ltr\" class=\"sandpack sandpack--codeblock rounded-2xl h-full w-full overflow-x-auto flex items-center bg-wash dark:bg-gray-95 shadow-lg my-8\" style=\"contain:content\">\n<div class=\"sp-wrapper\">\n<div class=\"sp-stack\">\n<div class=\"sp-code-editor\">\n<pre class=\"sp-cm sp-pristine sp-javascript flex align-start\"><code class=\"sp-pre-placeholder grow-[2]\"><p><span class=\"sp-syntax-keyword\">const<\/span> <span class=\"sp-syntax-plain\">postponed<\/span> = <span class=\"sp-syntax-keyword\">await<\/span> <span class=\"sp-syntax-definition\">getPostponedState<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-plain\">request<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p><span class=\"sp-syntax-keyword\">const<\/span> <span class=\"sp-syntax-plain\">resumeStream<\/span> = <span class=\"sp-syntax-keyword\">await<\/span> <span class=\"sp-syntax-definition\">resume<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\"><span class=\"sp-syntax-definition\">App<\/span> <span class=\"sp-syntax-punctuation\">\/&gt;<\/span><span class=\"sp-syntax-punctuation\">,<\/span> <span class=\"sp-syntax-plain\">postponed<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/span><\/p><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><!--\/$--><\/p>\n<p class=\"whitespace-pre-wrap my-4\">Or you can call <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">resumeAndPrerender<\/code> to resume to get static HTML for SSG:<\/p>\n<p><!--$--><\/p>\n<div dir=\"ltr\" class=\"sandpack sandpack--codeblock rounded-2xl h-full w-full overflow-x-auto flex items-center bg-wash dark:bg-gray-95 shadow-lg my-8\" style=\"contain:content\">\n<div class=\"sp-wrapper\">\n<div class=\"sp-stack\">\n<div class=\"sp-code-editor\">\n<pre class=\"sp-cm sp-pristine sp-javascript flex align-start\"><code class=\"sp-pre-placeholder grow-[2]\"><p><span class=\"sp-syntax-keyword\">const<\/span> <span class=\"sp-syntax-plain\">postponedState<\/span> = <span class=\"sp-syntax-keyword\">await<\/span> <span class=\"sp-syntax-definition\">getPostponedState<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-plain\">request<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/p><p><span class=\"sp-syntax-keyword\">const<\/span> <span class=\"sp-syntax-punctuation\">{<\/span> <span class=\"sp-syntax-property\">prelude<\/span> <span class=\"sp-syntax-punctuation\">}<\/span> = <span class=\"sp-syntax-keyword\">await<\/span> <span class=\"sp-syntax-definition\">resumeAndPrerender<\/span><span class=\"sp-syntax-punctuation\">(<\/span><span class=\"sp-syntax-punctuation\"><span class=\"sp-syntax-definition\">App<\/span> <span class=\"sp-syntax-punctuation\">\/&gt;<\/span><span class=\"sp-syntax-punctuation\">,<\/span> <span class=\"sp-syntax-plain\">postponedState<\/span><span class=\"sp-syntax-punctuation\">)<\/span><span class=\"sp-syntax-punctuation\">;<\/span><br\/><\/span><\/p><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><!--\/$--><\/p>\n<p class=\"whitespace-pre-wrap my-4\">For more info, see the docs for the new APIs:<\/p>\n<ul class=\"ms-6 my-3 list-disc\">\n<li class=\"leading-relaxed mb-1\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">react-dom\/server<\/code>\n<\/li>\n<li class=\"leading-relaxed mb-1\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">react-dom\/static<\/code>\n<\/li>\n<\/ul>\n<p class=\"whitespace-pre-wrap my-4\">Additionally, the prerender apis now return a <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">postpone<\/code> state to pass to the <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">resume<\/code> apis.<\/p>\n<hr class=\"my-6 block border-b border-t-0 border-border dark:border-border-dark\"\/>\n<h2 id=\"notable-changes\" class=\"mdx-heading text-3xl font-display leading-10 text-primary dark:text-primary-dark font-bold my-6\">Notable Changes <\/h2>\n<h3 id=\"batching-suspense-boundaries-for-ssr\" class=\"mdx-heading text-2xl font-display leading-9 text-primary dark:text-primary-dark font-bold my-6\">Batching Suspense Boundaries for SSR <\/h3>\n<p class=\"whitespace-pre-wrap my-4\">We fixed a behavioral bug where Suspense boundaries would reveal differently depending on if they were rendered on the client or when streaming from server-side rendering.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">Starting in 19.2, React will batch reveals of server-rendered Suspense boundaries for a short time, to allow more content to be revealed together and align with the client-rendered behavior.<\/p>\n<figure class=\"flex flex-col px-0 p-0 sm:p-10 first:mt-0 mt-10 sm:mt-0 justify-center items-center\">\n<div class=\"dark-image\"><img alt=\"Diagram with three sections, with an arrow transitioning each section in between. The first section contains a page rectangle showing a glimmer loading state with faded bars. The second panel shows the top half of the page revealed and highlighted in blue. The third panel shows the entire the page revealed and highlighted in blue.\" loading=\"lazy\" width=\"1270\" height=\"162\" decoding=\"async\" data-nimg=\"1\" style=\"color:transparent\" srcset=\"\/_next\/image?url=%2Fimages%2Fdocs%2Fdiagrams%2F19_2_batching_before.dark.png&amp;w=1920&amp;q=75 1x, \/_next\/image?url=%2Fimages%2Fdocs%2Fdiagrams%2F19_2_batching_before.dark.png&amp;w=3840&amp;q=75 2x\" src=\"https:\/\/react.dev\/_next\/image?url=%2Fimages%2Fdocs%2Fdiagrams%2F19_2_batching_before.dark.png&amp;w=3840&amp;q=75\"\/><\/div>\n<div class=\"light-image\"><img alt=\"Diagram with three sections, with an arrow transitioning each section in between. The first section contains a page rectangle showing a glimmer loading state with faded bars. The second panel shows the top half of the page revealed and highlighted in blue. The third panel shows the entire the page revealed and highlighted in blue.\" loading=\"lazy\" width=\"1270\" height=\"162\" decoding=\"async\" data-nimg=\"1\" style=\"color:transparent\" srcset=\"\/_next\/image?url=%2Fimages%2Fdocs%2Fdiagrams%2F19_2_batching_before.png&amp;w=1920&amp;q=75 1x, \/_next\/image?url=%2Fimages%2Fdocs%2Fdiagrams%2F19_2_batching_before.png&amp;w=3840&amp;q=75 2x\" src=\"https:\/\/react.dev\/_next\/image?url=%2Fimages%2Fdocs%2Fdiagrams%2F19_2_batching_before.png&amp;w=3840&amp;q=75\"\/><\/div>\n<div class=\"w-full flex justify-center\"><figcaption class=\"p-1 sm:p-2 mt-0 sm:mt-0 text-gray-40 text-base lg:text-lg text-center leading-tight table-caption max-w-lg\">\n<p class=\"whitespace-pre-wrap my-4\">Previously, during streaming server-side rendering, suspense content would immediately replace fallbacks.<\/p>\n<\/figcaption><\/div>\n<\/figure>\n<figure class=\"flex flex-col px-0 p-0 sm:p-10 first:mt-0 mt-10 sm:mt-0 justify-center items-center\">\n<div class=\"dark-image\"><img alt=\"Diagram with three sections, with an arrow transitioning each section in between. The first section contains a page rectangle showing a glimmer loading state with faded bars. The second panel shows the same page. The third panel shows the entire the page revealed and highlighted in blue.\" loading=\"lazy\" width=\"1270\" height=\"162\" decoding=\"async\" data-nimg=\"1\" style=\"color:transparent\" srcset=\"\/_next\/image?url=%2Fimages%2Fdocs%2Fdiagrams%2F19_2_batching_after.dark.png&amp;w=1920&amp;q=75 1x, \/_next\/image?url=%2Fimages%2Fdocs%2Fdiagrams%2F19_2_batching_after.dark.png&amp;w=3840&amp;q=75 2x\" src=\"https:\/\/react.dev\/_next\/image?url=%2Fimages%2Fdocs%2Fdiagrams%2F19_2_batching_after.dark.png&amp;w=3840&amp;q=75\"\/><\/div>\n<div class=\"light-image\"><img alt=\"Diagram with three sections, with an arrow transitioning each section in between. The first section contains a page rectangle showing a glimmer loading state with faded bars. The second panel shows the same page. The third panel shows the entire the page revealed and highlighted in blue.\" loading=\"lazy\" width=\"1270\" height=\"162\" decoding=\"async\" data-nimg=\"1\" style=\"color:transparent\" srcset=\"\/_next\/image?url=%2Fimages%2Fdocs%2Fdiagrams%2F19_2_batching_after.png&amp;w=1920&amp;q=75 1x, \/_next\/image?url=%2Fimages%2Fdocs%2Fdiagrams%2F19_2_batching_after.png&amp;w=3840&amp;q=75 2x\" src=\"https:\/\/react.dev\/_next\/image?url=%2Fimages%2Fdocs%2Fdiagrams%2F19_2_batching_after.png&amp;w=3840&amp;q=75\"\/><\/div>\n<div class=\"w-full flex justify-center\"><figcaption class=\"p-1 sm:p-2 mt-0 sm:mt-0 text-gray-40 text-base lg:text-lg text-center leading-tight table-caption max-w-lg\">\n<p class=\"whitespace-pre-wrap my-4\">In React 19.2, suspense boundaries are batched for a small amount of time, to allow revealing more content together.<\/p>\n<\/figcaption><\/div>\n<\/figure>\n<p class=\"whitespace-pre-wrap my-4\">This fix also prepares apps for supporting <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\"><viewtransition\/><\/code> for Suspense during SSR. By revealing more content together, animations can run in larger batches of content, and avoid chaining animations of content that stream in close together.<\/p>\n<div class=\"expandable-callout pt-8 pb-4 px-5 sm:px-8 my-8 relative rounded-none shadow-inner-border -mx-5 sm:mx-auto sm:rounded-2xl bg-green-5 dark:bg-green-60 dark:bg-opacity-20 text-primary dark:text-primary-dark text-lg\">\n<h3 class=\"text-2xl font-display font-bold text-green-60 dark:text-green-40\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"inline me-2 mb-1 text-lg text-green-60 dark:text-green-40\" width=\"2em\" height=\"2em\" viewbox=\"0 0 72 72\" fill=\"none\"><g clip-path=\"url(#clip0_40_48064)\"><path d=\"M24 27C24 25.3431 25.3431 24 27 24H45C46.6569 24 48 25.3431 48 27C48 28.6569 46.6569 30 45 30H27C25.3431 30 24 28.6569 24 27Z\" fill=\"currentColor\"\/><path d=\"M24 39C24 37.3431 25.3431 36 27 36H39C40.6569 36 42 37.3431 42 39C42 40.6569 40.6569 42 39 42H27C25.3431 42 24 40.6569 24 39Z\" fill=\"currentColor\"\/><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M12 18C12 13.0294 16.0294 9 21 9H51C55.9706 9 60 13.0294 60 18V54C60 58.9706 55.9706 63 51 63H21C16.0294 63 12 58.9706 12 54V18ZM21 15H51C52.6569 15 54 16.3431 54 18V54C54 55.6569 52.6569 57 51 57H21C19.3431 57 18 55.6569 18 54V18C18 16.3431 19.3431 15 21 15Z\" fill=\"currentColor\"\/><\/g><defs><clippath id=\"clip0_40_48064\"><rect width=\"72\" height=\"72\" fill=\"white\"\/><\/clippath><\/defs><\/svg>Note<\/h3>\n<div class=\"relative\">\n<div class=\"py-2\">\n<p class=\"whitespace-pre-wrap my-4\">React uses heuristics to ensure throttling does not impact core web vitals and search ranking.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">For example, if the total page load time is approaching 2.5s (which is the time considered \u201cgood\u201d for <a target=\"_blank\" href=\"https:\/\/web.dev\/articles\/lcp\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">LCP<\/a>), React will stop batching and reveal content immediately so that the throttling is not the reason to miss the metric.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<hr class=\"my-6 block border-b border-t-0 border-border dark:border-border-dark\"\/>\n<h3 id=\"ssr-web-streams-support-for-node\" class=\"mdx-heading text-2xl font-display leading-9 text-primary dark:text-primary-dark font-bold my-6\">SSR: Web Streams support for Node <\/h3>\n<p class=\"whitespace-pre-wrap my-4\">React 19.2 adds support for Web Streams for streaming SSR in Node.js:<\/p>\n<p class=\"whitespace-pre-wrap my-4\">As well as the new <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">resume<\/code> APIs:<\/p>\n<div class=\"expandable-callout pt-8 pb-4 px-5 sm:px-8 my-8 relative rounded-none shadow-inner-border -mx-5 sm:mx-auto sm:rounded-2xl bg-yellow-5 dark:bg-yellow-60 dark:bg-opacity-20\">\n<h3 class=\"text-2xl font-display font-bold text-yellow-50 dark:text-yellow-40\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"inline me-2 mb-1 text-lg text-yellow-50 dark:text-yellow-40\" width=\"2em\" height=\"2em\" viewbox=\"0 0 72 72\" fill=\"none\"><g clip-path=\"url(#clip0_738_836)\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M27 48L27 57.3409L40.0772 48L55.6975 48C57.1595 48 58.1986 47.0112 58.3851 45.8604C59.1824 40.9398 60 34.619 60 29.625C60 24.7282 59.2125 18.7546 58.4302 14.0813C58.2445 12.9721 57.2326 12 55.7805 12L16.2195 12C14.7674 12 13.7555 12.9721 13.5698 14.0813C12.7875 18.7546 12 24.7282 12 29.625C12 34.619 12.8176 40.9398 13.6149 45.8604C13.8014 47.0112 14.8404 48 16.3025 48H27ZM42 54H55.6975C59.9534 54 63.6271 51.0213 64.3078 46.8201C65.1161 41.8322 66 35.1209 66 29.625C66 24.2196 65.1449 17.8522 64.3478 13.0906C63.6513 8.93026 59.9987 6 55.7805 6H16.2195C12.0013 6 8.34867 8.93026 7.65218 13.0906C6.85505 17.8522 6 24.2196 6 29.625C6 35.1209 6.88391 41.8322 7.69215 46.8201C8.37291 51.0213 12.0466 54 16.3025 54H21L21 63.1704C21 65.6106 23.7581 67.0299 25.7437 65.6116L42 54ZM39 39.3686C39 40.9422 38 41.9912 36 41.9912C34 41.9912 33 40.9422 33 39.3686C33 37.7951 34 36.746 36 36.746C38 36.746 39 37.7951 39 39.3686ZM38.1771 20.2412C38.1771 18.9986 37.1697 17.9912 35.9271 17.9912C34.6845 17.9912 33.6771 18.9986 33.6771 20.2412V31.5956C33.6771 32.8382 34.6845 33.8456 35.9271 33.8456C37.1697 33.8456 38.1771 32.8382 38.1771 31.5956V20.2412Z\" fill=\"currentColor\"\/><\/g><defs><clippath id=\"clip0_738_836\"><rect width=\"72\" height=\"72\" fill=\"white\"\/><\/clippath><\/defs><\/svg>Pitfall<\/h3>\n<div class=\"relative\">\n<div class=\"py-2\">\n<h4 id=\"prefer-node-streams-for-server-side-rendering-in-nodejs\" class=\"mdx-heading text-xl font-display font-bold leading-9 my-4\">Prefer Node Streams for server-side rendering in Node.js <\/h4>\n<p class=\"whitespace-pre-wrap my-4\">In Node.js environments, we still highly recommend using the Node Streams APIs:<\/p>\n<p class=\"whitespace-pre-wrap my-4\">This is because Node Streams are much faster than Web Streams in Node, and Web Streams do not support compression by default, leading to users accidentally missing the benefits of streaming.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<hr class=\"my-6 block border-b border-t-0 border-border dark:border-border-dark\"\/>\n<h3 id=\"eslint-plugin-react-hooks\" class=\"mdx-heading text-2xl font-display leading-9 text-primary dark:text-primary-dark font-bold my-6\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">eslint-plugin-react-hooks<\/code> v6 <\/h3>\n<p class=\"whitespace-pre-wrap my-4\">We also published <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">eslint-plugin-react-hooks@6.1.0<\/code> with flat config by default in the <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">recommended<\/code> preset, and opt-in for new React Compiler powered rules.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">To continue using the legacy config, you can change to <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">recommended-legacy<\/code>:<\/p>\n<p><!--$--><\/p>\n<div dir=\"ltr\" class=\"sandpack sandpack--codeblock rounded-2xl h-full w-full overflow-x-auto flex items-center bg-wash dark:bg-gray-95 shadow-lg my-8\" style=\"contain:content\">\n<div class=\"sp-wrapper\">\n<div class=\"sp-stack\">\n<div class=\"sp-code-editor\">\n<pre class=\"sp-cm sp-pristine sp-javascript flex align-start\"><code class=\"sp-pre-placeholder grow-[2]\"><p>- <span class=\"sp-syntax-keyword\">extends<\/span><span class=\"sp-syntax-punctuation\">:<\/span> <span class=\"sp-syntax-punctuation\">[<\/span><span class=\"sp-syntax-string\">'plugin:react-hooks\/recommended'<\/span><span class=\"sp-syntax-punctuation\">]<\/span><br\/><\/p><p>+ <span class=\"sp-syntax-keyword\">extends<\/span><span class=\"sp-syntax-punctuation\">:<\/span> <span class=\"sp-syntax-punctuation\">[<\/span><span class=\"sp-syntax-string\">'plugin:react-hooks\/recommended-legacy'<\/span><span class=\"sp-syntax-punctuation\">]<\/span><\/p><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><!--\/$--><\/p>\n<p class=\"whitespace-pre-wrap my-4\">For a full list of compiler enabled rules, <a target=\"_blank\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\" href=\"http:\/\/react.dev\/reference\/eslint-plugin-react-hooks#additional-rules\">check out the linter docs<\/a>.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">Check out the <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">eslint-plugin-react-hooks<\/code> <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/blob\/main\/packages\/eslint-plugin-react-hooks\/CHANGELOG.md#610\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">changelog for a full list of changes<\/a>.<\/p>\n<hr class=\"my-6 block border-b border-t-0 border-border dark:border-border-dark\"\/>\n<h3 id=\"update-the-default-useid-prefix\" class=\"mdx-heading text-2xl font-display leading-9 text-primary dark:text-primary-dark font-bold my-6\">Update the default <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">useId<\/code> prefix <\/h3>\n<p class=\"whitespace-pre-wrap my-4\">In 19.2, we\u2019re updating the default <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">useId<\/code> prefix from <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">:r:<\/code> (19.0.0) or <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">\u00abr\u00bb<\/code> (19.1.0) to <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">_r_<\/code>.<\/p>\n<p class=\"whitespace-pre-wrap my-4\">The original intent of using a special character that was not valid for CSS selectors was that it would be unlikely to collide with IDs written by users. However, to support View Transitions, we need to ensure that IDs generated by <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">useId<\/code> are valid for <code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">view-transition-name<\/code> and XML 1.0 names.<\/p>\n<hr class=\"my-6 block border-b border-t-0 border-border dark:border-border-dark\"\/>\n<h2 id=\"changelog\" class=\"mdx-heading text-3xl font-display leading-10 text-primary dark:text-primary-dark font-bold my-6\">Changelog <\/h2>\n<p class=\"whitespace-pre-wrap my-4\">Other notable changes<\/p>\n<ul class=\"ms-6 my-3 list-disc\">\n<li class=\"leading-relaxed mb-1\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">react-dom<\/code>: Allow nonce to be used on hoistable styles <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/pull\/32461\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">#32461<\/a><\/li>\n<li class=\"leading-relaxed mb-1\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">react-dom<\/code>: Warn for using a React owned node as a Container if it also has text content <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/pull\/32774\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">#32774<\/a><\/li>\n<\/ul>\n<p class=\"whitespace-pre-wrap my-4\">Notable bug fixes<\/p>\n<ul class=\"ms-6 my-3 list-disc\">\n<li class=\"leading-relaxed mb-1\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">react<\/code>: Stringify context as \u201cSomeContext\u201d instead of \u201cSomeContext.Provider\u201d <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/pull\/33507\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">#33507<\/a><\/li>\n<li class=\"leading-relaxed mb-1\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">react<\/code>: Fix infinite useDeferredValue loop in popstate event <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/pull\/32821\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">#32821<\/a><\/li>\n<li class=\"leading-relaxed mb-1\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">react<\/code>: Fix a bug when an initial value was passed to useDeferredValue <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/pull\/34376\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">#34376<\/a><\/li>\n<li class=\"leading-relaxed mb-1\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">react<\/code>: Fix a crash when submitting forms with Client Actions <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/pull\/33055\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">#33055<\/a><\/li>\n<li class=\"leading-relaxed mb-1\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">react<\/code>: Hide\/unhide the content of dehydrated suspense boundaries if they resuspend <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/pull\/32900\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">#32900<\/a><\/li>\n<li class=\"leading-relaxed mb-1\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">react<\/code>: Avoid stack overflow on wide trees during Hot Reload <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/pull\/34145\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">#34145<\/a><\/li>\n<li class=\"leading-relaxed mb-1\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">react<\/code>: Improve component stacks in various places <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/pull\/33629\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">#33629<\/a>, <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/pull\/33724\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">#33724<\/a>, <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/pull\/32735\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">#32735<\/a>, <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/pull\/33723\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">#33723<\/a><\/li>\n<li class=\"leading-relaxed mb-1\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">react<\/code>: Fix a bug with React.use inside React.lazy-ed Component <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/pull\/33941\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">#33941<\/a><\/li>\n<li class=\"leading-relaxed mb-1\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">react-dom<\/code>: Stop warning when ARIA 1.3 attributes are used <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/pull\/34264\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">#34264<\/a><\/li>\n<li class=\"leading-relaxed mb-1\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">react-dom<\/code>: Fix a bug with deeply nested Suspense inside Suspense fallbacks <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/pull\/33467\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">#33467<\/a><\/li>\n<li class=\"leading-relaxed mb-1\"><code dir=\"ltr\" class=\"inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline bg-gray-30 bg-opacity-10 py-px\">react-dom<\/code>: Avoid hanging when suspending after aborting while rendering <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/pull\/34192\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">#34192<\/a><\/li>\n<\/ul>\n<p class=\"whitespace-pre-wrap my-4\">For a full list of changes, please see the <a target=\"_blank\" href=\"https:\/\/github.com\/facebook\/react\/blob\/main\/CHANGELOG.md\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">Changelog<\/a>.<\/p>\n<hr class=\"my-6 block border-b border-t-0 border-border dark:border-border-dark\"\/>\n<p class=\"whitespace-pre-wrap my-4\"><em>Thanks to <a target=\"_blank\" href=\"https:\/\/bsky.app\/profile\/ricky.fm\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">Ricky Hanlon<\/a> for <a target=\"_blank\" href=\"https:\/\/www.youtube.com\/shorts\/T9X3YkgZRG0\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">writing this post<\/a>, <a target=\"_blank\" href=\"https:\/\/bsky.app\/profile\/danabra.mov\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">Dan Abramov<\/a>, <a target=\"_blank\" href=\"https:\/\/twitter.com\/mattcarrollcode\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">Matt Carroll<\/a>, <a target=\"_blank\" href=\"https:\/\/jackpope.me\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">Jack Pope<\/a>, and <a target=\"_blank\" href=\"https:\/\/x.com\/en_JS\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal\">Joe Savona<\/a> for reviewing this post.<\/em><\/p>\n<\/div>\n<p><script async src=\"\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><br \/>\n<br \/>\n<br \/><a href=\"https:\/\/react.dev\/blog\/2025\/10\/01\/react-19-2\">\u5143\u306e\u8a18\u4e8b\u3092\u78ba\u8a8d\u3059\u308b <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"October 1, 2025 by The React Team React 19.2 is now available on npm! This is our third release in the last ye [&hellip;]","protected":false},"author":1,"featured_media":7787,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[],"class_list":["post-7786","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-hatena-blog"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>React 19.2 \u2013 React - \u30dd\u30b1\u30b3\u30f3<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/react.dev\/blog\/2025\/10\/01\/react-19-2\" \/>\n<meta property=\"og:locale\" content=\"ja_JP\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"React 19.2 \u2013 React - \u30dd\u30b1\u30b3\u30f3\" \/>\n<meta property=\"og:description\" content=\"October 1, 2025 by The React Team React 19.2 is now available on npm! This is our third release in the last ye [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/react.dev\/blog\/2025\/10\/01\/react-19-2\" \/>\n<meta property=\"og:site_name\" content=\"\u30dd\u30b1\u30b3\u30f3\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-02T01:49:33+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/pokecon.jp\/job\/wp-content\/uploads\/2025\/10\/og-blog.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1080\" \/>\n\t<meta property=\"og:image:height\" content=\"567\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"info@pokecon.jp\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u57f7\u7b46\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"info@pokecon.jp\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u63a8\u5b9a\u8aad\u307f\u53d6\u308a\u6642\u9593\" \/>\n\t<meta name=\"twitter:data2\" content=\"8\u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/react.dev\\\/blog\\\/2025\\\/10\\\/01\\\/react-19-2#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/pokecon.jp\\\/job\\\/7786\\\/\"},\"author\":{\"name\":\"info@pokecon.jp\",\"@id\":\"https:\\\/\\\/pokecon.jp\\\/job\\\/#\\\/schema\\\/person\\\/16c9f07b1ba984d165d9aee259bda997\"},\"headline\":\"React 19.2 \u2013 React\",\"datePublished\":\"2025-10-02T01:49:33+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/pokecon.jp\\\/job\\\/7786\\\/\"},\"wordCount\":1455,\"image\":{\"@id\":\"https:\\\/\\\/react.dev\\\/blog\\\/2025\\\/10\\\/01\\\/react-19-2#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/pokecon.jp\\\/job\\\/wp-content\\\/uploads\\\/2025\\\/10\\\/og-blog.png\",\"articleSection\":[\"\u306f\u3066\u306a\u30d6\u30ed\u30b0\"],\"inLanguage\":\"ja\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/pokecon.jp\\\/job\\\/7786\\\/\",\"url\":\"https:\\\/\\\/react.dev\\\/blog\\\/2025\\\/10\\\/01\\\/react-19-2\",\"name\":\"React 19.2 \u2013 React - \u30dd\u30b1\u30b3\u30f3\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/pokecon.jp\\\/job\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/react.dev\\\/blog\\\/2025\\\/10\\\/01\\\/react-19-2#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/react.dev\\\/blog\\\/2025\\\/10\\\/01\\\/react-19-2#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/pokecon.jp\\\/job\\\/wp-content\\\/uploads\\\/2025\\\/10\\\/og-blog.png\",\"datePublished\":\"2025-10-02T01:49:33+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/pokecon.jp\\\/job\\\/#\\\/schema\\\/person\\\/16c9f07b1ba984d165d9aee259bda997\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/react.dev\\\/blog\\\/2025\\\/10\\\/01\\\/react-19-2#breadcrumb\"},\"inLanguage\":\"ja\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/react.dev\\\/blog\\\/2025\\\/10\\\/01\\\/react-19-2\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"ja\",\"@id\":\"https:\\\/\\\/react.dev\\\/blog\\\/2025\\\/10\\\/01\\\/react-19-2#primaryimage\",\"url\":\"https:\\\/\\\/pokecon.jp\\\/job\\\/wp-content\\\/uploads\\\/2025\\\/10\\\/og-blog.png\",\"contentUrl\":\"https:\\\/\\\/pokecon.jp\\\/job\\\/wp-content\\\/uploads\\\/2025\\\/10\\\/og-blog.png\",\"width\":1080,\"height\":567},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/react.dev\\\/blog\\\/2025\\\/10\\\/01\\\/react-19-2#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u30db\u30fc\u30e0\",\"item\":\"https:\\\/\\\/pokecon.jp\\\/job\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"React 19.2 \u2013 React\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/pokecon.jp\\\/job\\\/#website\",\"url\":\"https:\\\/\\\/pokecon.jp\\\/job\\\/\",\"name\":\"\u30dd\u30b1\u30b3\u30f3\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/pokecon.jp\\\/job\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"ja\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/pokecon.jp\\\/job\\\/#\\\/schema\\\/person\\\/16c9f07b1ba984d165d9aee259bda997\",\"name\":\"info@pokecon.jp\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ja\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/2b0549cd9f7907c092ca5fbb283baf72337f235726e4b46fa39ec0b701ac2fe2?s=96&d=wavatar&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/2b0549cd9f7907c092ca5fbb283baf72337f235726e4b46fa39ec0b701ac2fe2?s=96&d=wavatar&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/2b0549cd9f7907c092ca5fbb283baf72337f235726e4b46fa39ec0b701ac2fe2?s=96&d=wavatar&r=g\",\"caption\":\"info@pokecon.jp\"},\"url\":\"https:\\\/\\\/pokecon.jp\\\/job\\\/author\\\/infopokecon-jp\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"React 19.2 \u2013 React - \u30dd\u30b1\u30b3\u30f3","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/react.dev\/blog\/2025\/10\/01\/react-19-2","og_locale":"ja_JP","og_type":"article","og_title":"React 19.2 \u2013 React - \u30dd\u30b1\u30b3\u30f3","og_description":"October 1, 2025 by The React Team React 19.2 is now available on npm! This is our third release in the last ye [&hellip;]","og_url":"https:\/\/react.dev\/blog\/2025\/10\/01\/react-19-2","og_site_name":"\u30dd\u30b1\u30b3\u30f3","article_published_time":"2025-10-02T01:49:33+00:00","og_image":[{"width":1080,"height":567,"url":"https:\/\/pokecon.jp\/job\/wp-content\/uploads\/2025\/10\/og-blog.png","type":"image\/png"}],"author":"info@pokecon.jp","twitter_card":"summary_large_image","twitter_misc":{"\u57f7\u7b46\u8005":"info@pokecon.jp","\u63a8\u5b9a\u8aad\u307f\u53d6\u308a\u6642\u9593":"8\u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/react.dev\/blog\/2025\/10\/01\/react-19-2#article","isPartOf":{"@id":"https:\/\/pokecon.jp\/job\/7786\/"},"author":{"name":"info@pokecon.jp","@id":"https:\/\/pokecon.jp\/job\/#\/schema\/person\/16c9f07b1ba984d165d9aee259bda997"},"headline":"React 19.2 \u2013 React","datePublished":"2025-10-02T01:49:33+00:00","mainEntityOfPage":{"@id":"https:\/\/pokecon.jp\/job\/7786\/"},"wordCount":1455,"image":{"@id":"https:\/\/react.dev\/blog\/2025\/10\/01\/react-19-2#primaryimage"},"thumbnailUrl":"https:\/\/pokecon.jp\/job\/wp-content\/uploads\/2025\/10\/og-blog.png","articleSection":["\u306f\u3066\u306a\u30d6\u30ed\u30b0"],"inLanguage":"ja"},{"@type":"WebPage","@id":"https:\/\/pokecon.jp\/job\/7786\/","url":"https:\/\/react.dev\/blog\/2025\/10\/01\/react-19-2","name":"React 19.2 \u2013 React - \u30dd\u30b1\u30b3\u30f3","isPartOf":{"@id":"https:\/\/pokecon.jp\/job\/#website"},"primaryImageOfPage":{"@id":"https:\/\/react.dev\/blog\/2025\/10\/01\/react-19-2#primaryimage"},"image":{"@id":"https:\/\/react.dev\/blog\/2025\/10\/01\/react-19-2#primaryimage"},"thumbnailUrl":"https:\/\/pokecon.jp\/job\/wp-content\/uploads\/2025\/10\/og-blog.png","datePublished":"2025-10-02T01:49:33+00:00","author":{"@id":"https:\/\/pokecon.jp\/job\/#\/schema\/person\/16c9f07b1ba984d165d9aee259bda997"},"breadcrumb":{"@id":"https:\/\/react.dev\/blog\/2025\/10\/01\/react-19-2#breadcrumb"},"inLanguage":"ja","potentialAction":[{"@type":"ReadAction","target":["https:\/\/react.dev\/blog\/2025\/10\/01\/react-19-2"]}]},{"@type":"ImageObject","inLanguage":"ja","@id":"https:\/\/react.dev\/blog\/2025\/10\/01\/react-19-2#primaryimage","url":"https:\/\/pokecon.jp\/job\/wp-content\/uploads\/2025\/10\/og-blog.png","contentUrl":"https:\/\/pokecon.jp\/job\/wp-content\/uploads\/2025\/10\/og-blog.png","width":1080,"height":567},{"@type":"BreadcrumbList","@id":"https:\/\/react.dev\/blog\/2025\/10\/01\/react-19-2#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u30db\u30fc\u30e0","item":"https:\/\/pokecon.jp\/job\/"},{"@type":"ListItem","position":2,"name":"React 19.2 \u2013 React"}]},{"@type":"WebSite","@id":"https:\/\/pokecon.jp\/job\/#website","url":"https:\/\/pokecon.jp\/job\/","name":"\u30dd\u30b1\u30b3\u30f3","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/pokecon.jp\/job\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"ja"},{"@type":"Person","@id":"https:\/\/pokecon.jp\/job\/#\/schema\/person\/16c9f07b1ba984d165d9aee259bda997","name":"info@pokecon.jp","image":{"@type":"ImageObject","inLanguage":"ja","@id":"https:\/\/secure.gravatar.com\/avatar\/2b0549cd9f7907c092ca5fbb283baf72337f235726e4b46fa39ec0b701ac2fe2?s=96&d=wavatar&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/2b0549cd9f7907c092ca5fbb283baf72337f235726e4b46fa39ec0b701ac2fe2?s=96&d=wavatar&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/2b0549cd9f7907c092ca5fbb283baf72337f235726e4b46fa39ec0b701ac2fe2?s=96&d=wavatar&r=g","caption":"info@pokecon.jp"},"url":"https:\/\/pokecon.jp\/job\/author\/infopokecon-jp\/"}]}},"_links":{"self":[{"href":"https:\/\/pokecon.jp\/job\/wp-json\/wp\/v2\/posts\/7786","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pokecon.jp\/job\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pokecon.jp\/job\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pokecon.jp\/job\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pokecon.jp\/job\/wp-json\/wp\/v2\/comments?post=7786"}],"version-history":[{"count":1,"href":"https:\/\/pokecon.jp\/job\/wp-json\/wp\/v2\/posts\/7786\/revisions"}],"predecessor-version":[{"id":7788,"href":"https:\/\/pokecon.jp\/job\/wp-json\/wp\/v2\/posts\/7786\/revisions\/7788"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pokecon.jp\/job\/wp-json\/wp\/v2\/media\/7787"}],"wp:attachment":[{"href":"https:\/\/pokecon.jp\/job\/wp-json\/wp\/v2\/media?parent=7786"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pokecon.jp\/job\/wp-json\/wp\/v2\/categories?post=7786"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pokecon.jp\/job\/wp-json\/wp\/v2\/tags?post=7786"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}