You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/blog/2025/09/30/react-19-2.md
+52-33Lines changed: 52 additions & 33 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,20 +15,11 @@ React 19.2 is now available on npm!
15
15
16
16
</Intro>
17
17
18
+
This is our third release in the last year, following React 19 in December and React 19.1 in June. In this post, we'll give an overview of the new features in React 19.2, and highlight some notable changes.
18
19
19
-
<Note>
20
-
21
-
React Conf 2025 is October 7–8 in Henderson, Nevada!
20
+
<InlineToc />
22
21
23
-
Watch the livestream on [the React Conf website](https://conf.react.dev).
24
-
25
-
</Note>
26
22
27
-
React 19.2 is our third release in the last year, following React 19 in December and React 19.1 in June.
28
-
29
-
This release continues to build on the scheduling capabilities of concurrent rendering with Activity, adds performance tracks to help optimize your code for concurrent rendering, and new APIs to improve the developer experience.
30
-
31
-
In this post, we'll give an overview of the new features in React 19.2, and how you can adopt them.
32
23
33
24
---
34
25
@@ -38,19 +29,30 @@ In this post, we'll give an overview of the new features in React 19.2, and how
38
29
39
30
`<Activity>` lets you break your app into "activities" that can be controlled and prioritized.
40
31
41
-
In React 19.2, Activity supports two modes: `visible` and `hidden`:
32
+
You can use Activity as an alternative to conditionally rendering parts of your app:
42
33
43
34
```js
35
+
// Before
36
+
{isVisible &&<Page />}
37
+
38
+
// After
44
39
<Activity mode={isVisible ?'visible':'hidden'}>
45
40
<Page />
46
41
</Activity>
47
42
```
48
43
49
-
When an Activity is `visible` it’s rendered as normal on the client, and will defer hydration during SSR. When an Activity is `hidden` it is unmounted (adding `display:none` to the children) and is excluded from the SSR output. While an Activity is hidden, React will keep the hook and DOM state, and continue to render at a lower priority than anything visible on screen.
50
-
51
-
You can use Activity to pre-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, and allows back navigations to maintain state such as input fields.
44
+
In React 19.2, Activity supports two modes: `visible` and `hidden`.
52
45
53
-
For more information, see the last [React Labs post](/blog/2025/04/23/react-labs-view-transitions-activity-and-more#activity) and the [Activity docs](/reference/react/activity).
46
+
-`hidden`: hides the children, unmounts effects, and defers all updates until React has nothing left to work on.
47
+
-`visible`: shows the children, mounts effects, and allows updates to be processed normally.
48
+
49
+
This means you can pre-render and keep rendering hidden parts of the app without impacting the performance of anything visible on screen.
50
+
51
+
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.
52
+
53
+
In the future, we plan to add more modes to Activity for different use cases.
54
+
55
+
For examples on how to use Activity, check out the [Activity docs](/reference/react/activity).
54
56
55
57
---
56
58
@@ -76,29 +78,28 @@ For more information, see the [React Performance Tracks docs](/learn/react-perfo
76
78
77
79
### `useEffectEvent` {/*use-effect-event*/}
78
80
79
-
When using Effects you may want to read the most recent props or state inside an Effect without causing the Effect to re-run when those values change.
81
+
When using Effects you may want to read the most recent props or state inside an Effect without re-running the Effect when those values change. For example, in the following code the `theme` prop is used inside an Effect, but we don’t want the Effect to re-run when `theme` changes:
80
82
81
-
The typical workaround is to use a ref to store the latest `theme`, and read from that ref inside the Effect. This works, but it’s verbose and requires extra code, so in practice most users just disable the lint rule and leave the dependency out.
82
-
83
-
Disabling the lint rule creates a refactor hazard, because the linter cannot help you if you later add a dependency that should be included. Here, `threadId` is added after the initial implementation, but the Effect does not re-run when `threadId` changes because it was not added to the dependency array:
To solve this problem, React 19.2 introduces `useEffectEvent`, which lets you declare Effect Events that can be called inside Effects. Effect Events always access the latest values from props and state when they are invoked, so you can read the latest values without re-running the Effect.
98
+
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.
99
+
100
+
React 19.2 introduces `useEffectEvent`, which lets you declare "Effect Events" that can be called inside Effects. Effect Events always access the latest values from props and state when they are invoked, so you can read the latest values without re-running the Effect:
101
+
102
+
With `useEffectEvent`, we can define the `onConnected` callback as an "Effect Event". Now, it doesn't re-run when the values change, but it can still “see” the latest values of your props and state:
#### Please don't over use `useEffectEvent` {/*please-dont-over-use-useeffectevent*/}
124
+
125
+
We introduced `useEffectEvent` as an experimental API several years ago, and you may be curious why it took so long to ship. We've considered multiple alternatives, but all of them have different tradeoffs that can make it too easy to accidentally out of reactivity, especially if it is overused.
126
+
127
+
We're shipping `useEffectEvent` because it helps solve a common problem, but we recommend using it sparingly. In the future we may explore other APIs that can solve the same problem better.
128
+
129
+
</Note>
130
+
131
+
120
132
For more information, see [Separating Events from Effects](/learn/separating-events-from-effects) and the [`useEffectEvent` docs](/reference/react/useEffectEvent).
121
133
122
134
---
@@ -154,7 +166,7 @@ For more info, see the [`cacheSignal` docs](/reference/react/cacheSignal).
154
166
155
167
### Batching Suspense Boundaries for SSR {/*batching-suspense-boundaries-for-ssr*/}
156
168
157
-
We fixed a long-standing behavior bug where Suspense boundaries would reveal differently depending on if they were rendered on the client or when streaming from server-side rendering.
169
+
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.
158
170
159
171
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.
160
172
@@ -170,7 +182,7 @@ In React 19.2, suspense boundaries are batched for a small amount of time, to al
170
182
171
183
</Diagram>
172
184
173
-
This fix also prepares apps for supporting `<ViewTransition>` for Suspense during SSR. By revealing more content together, animations can run in larger batches of content, and avoid chaining animations of content that streams in close together.
185
+
This fix also prepares apps for supporting `<ViewTransition>` 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.
174
186
175
187
<Note>
176
188
@@ -190,7 +202,14 @@ React 19.2 adds support for Web Streams for streaming SSR in Node.js:
190
202
191
203
<Pitfall>
192
204
193
-
We still highly recommend using Node Streams for streaming server-side rendering in Node environments because Node Streams are much faster than Web Streams, and Web Streams do not support compression by default, leading to users accidentally missing the benefits of streaming.
205
+
#### Prefer Node Streams for server-side rendering in Node.js {/*prefer-node-streams-for-server-side-rendering-in-nodejs*/}
206
+
207
+
In Node.js environments, we still highly recommend using the Node Streams APIs:
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.
194
213
195
214
</Pitfall>
196
215
@@ -218,10 +237,10 @@ Notable bug fixes
218
237
- `react`: Hide/unhide the content of dehydrated suspense boundaries if they resuspend [#32900](https://github.com/facebook/react/pull/32900)
219
238
- `react`: Avoid stack overflow on wide trees during Hot Reload [#34145](https://github.com/facebook/react/pull/34145)
220
239
- `react`: Improve component stacks in various places [#33629](https://github.com/facebook/react/pull/33629), [#33724](https://github.com/facebook/react/pull/33724), [#32735](https://github.com/facebook/react/pull/32735), [#33723](https://github.com/facebook/react/pull/33723)
221
-
- `react`: Fix a bug with React.use inside React.lazy-ed Component (@hi-ogawa [#33941](https://github.com/facebook/react/pull/33941)
222
-
- `react-dom`: Stop warning when ARIA 1.3 attributes are used (@Abdul-Omira [#34264](https://github.com/facebook/react/pull/34264)
240
+
- `react`: Fix a bug with React.use inside React.lazy-ed Component [#33941](https://github.com/facebook/react/pull/33941)
241
+
- `react-dom`: Stop warning when ARIA 1.3 attributes are used [#34264](https://github.com/facebook/react/pull/34264)
223
242
- `react-dom`: Fix a bug with deeply nested Suspense inside Suspense fallbacks [#33467](https://github.com/facebook/react/pull/33467)
224
-
- `react-dom`: Avoid hanging when suspending after aborting while rendering (@gnoff [#34192)]()
243
+
- `react-dom`: Avoid hanging when suspending after aborting while rendering [#34192](https://github.com/facebook/react/pull/34192)
225
244
226
245
For a full list of changes, please see the [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md).
Copy file name to clipboardExpand all lines: src/content/learn/reusing-logic-with-custom-hooks.md
-8Lines changed: 0 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -837,14 +837,6 @@ Every time your `ChatRoom` component re-renders, it passes the latest `roomId` a
837
837
838
838
### Passing event handlers to custom Hooks {/*passing-event-handlers-to-custom-hooks*/}
839
839
840
-
<Canary>
841
-
842
-
**The `useEffectEvent` API is currently only available in React’s Canary and Experimental channels.**
843
-
844
-
[Learn more about React’s release channels here.](/community/versioning-policy#all-release-channels)
845
-
846
-
</Canary>
847
-
848
840
As you start using `useChatRoom` in more components, you might want to let components customize its behavior. For example, currently, the logic for what to do when a message arrives is hardcoded inside the Hook:
Copy file name to clipboardExpand all lines: src/content/reference/react/useEffect.md
+1-9Lines changed: 1 addition & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1691,14 +1691,6 @@ Now that you define the `createOptions` function inside the Effect, the Effect i
1691
1691
1692
1692
### Reading the latest props and state from an Effect {/*reading-the-latest-props-and-state-from-an-effect*/}
1693
1693
1694
-
<Canary>
1695
-
1696
-
**The `useEffectEvent` API is currently only available in React’s Canary and Experimental channels.**
1697
-
1698
-
[Learn more about React’s release channels here.](/community/versioning-policy#all-release-channels)
1699
-
1700
-
</Canary>
1701
-
1702
1694
By default, when you read a reactive value from an Effect, you have to add it as a dependency. This ensures that your Effect "reacts" to every change of that value. For most dependencies, that's the behavior you want.
1703
1695
1704
1696
**However, sometimes you'll want to read the *latest* props and state from an Effect without "reacting" to them.** For example, imagine you want to log the number of the items in the shopping cart for every page visit:
@@ -1712,7 +1704,7 @@ function Page({ url, shoppingCart }) {
1712
1704
}
1713
1705
```
1714
1706
1715
-
<CanaryBadge /> **What if you want to log a new page visit after every `url` change, but *not* if only the `shoppingCart` changes?** You can't exclude `shoppingCart` from dependencies without breaking the [reactivity rules.](#specifying-reactive-dependencies) However, you can express that you *don't want* a piece of code to "react" to changes even though it is called from inside an Effect. [Declare an *Effect Event*](/learn/separating-events-from-effects#declaring-an-effect-event) with the [`useEffectEvent`](/reference/react/useEffectEvent) Hook, and move the code reading `shoppingCart` inside of it:
1707
+
**What if you want to log a new page visit after every `url` change, but *not* if only the `shoppingCart` changes?** You can't exclude `shoppingCart` from dependencies without breaking the [reactivity rules.](#specifying-reactive-dependencies) However, you can express that you *don't want* a piece of code to "react" to changes even though it is called from inside an Effect. [Declare an *Effect Event*](/learn/separating-events-from-effects#declaring-an-effect-event) with the [`useEffectEvent`](/reference/react/useEffectEvent) Hook, and move the code reading `shoppingCart` inside of it:
Copy file name to clipboardExpand all lines: src/content/reference/react/useEffectEvent.md
-10Lines changed: 0 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,17 +1,7 @@
1
1
---
2
2
title: useEffectEvent
3
-
version: canary
4
3
---
5
4
6
-
7
-
<Canary>
8
-
9
-
**The `useEffectEvent` API is currently only available in React’s Canary and Experimental channels.**
10
-
11
-
[Learn more about React’s release channels here.](/community/versioning-policy#all-release-channels)
12
-
13
-
</Canary>
14
-
15
5
<Intro>
16
6
17
7
`useEffectEvent` is a React Hook that lets you extract non-reactive logic from your Effects into a reusable function called an [Effect Event](/learn/separating-events-from-effects#declaring-an-effect-event).
0 commit comments