Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,76 @@
## 19.2.0 (October 1st, 2025)

Below is a list of all new features, APIs, and bug fixes.

Read the [React 19.2 release post](https://react.dev/blog/2025/10/01/react-19-2) for more information.

### New React Features

- [`<Activity>`](https://react.dev/reference/react/Activity): A new API to hide and restore the UI and internal state of its children.
- [`useEffectEvent`](https://react.dev/reference/react/useEffectEvent) is a React Hook that lets you extract non-reactive logic into an [Effect Event](https://react.dev/learn/separating-events-from-effects#declaring-an-effect-event).
- [`cacheSignal`](https://react.dev/reference/react/cacheSignal) (for RSCs) lets your know when the `cache()` lifetime is over.
- [React Performance tracks](https://react.dev/reference/developer-tooling/react-performance-tracks) appear on the Performance panel’s timeline in your browser developer tools

### New React DOM Features

- Added resume APIs for partial pre-rendering with Web Streams:
- [`resume`](https://react.dev/reference/react-dom/server/resume): to resume a prerender to a stream.
- [`resumeAndPrerender`](https://react.dev/reference/react-dom/static/resumeAndPrerender): to resume a prerender to HTML.
- Added resume APIs for partial pre-rendering with Node Streams:
- [`resumeToPipeableStream`](https://react.dev/reference/react-dom/server/resumeToPipeableStream): to resume a prerender to a stream.
- [`resumeAndPrerenderToNodeStream`](https://react.dev/reference/react-dom/static/resumeAndPrerenderToNodeStream): to resume a prerender to HTML.
- Updated [`prerender`](https://react.dev/reference/react-dom/static/prerender) APIs to return a `postponed` state that can be passed to the `resume` APIs.

### Notable changes

- React DOM now batches suspense boundary reveals, matching the behavior of client side rendering. This change is especially noticeable when animating the reveal of Suspense boundaries e.g. with the upcoming `<ViewTransition>` Component. React will batch as much reveals as possible before the first paint while trying to hit popular first-contentful paint metrics.
- Add Node Web Streams (`prerender`, `renderToReadableStream`) to server-side-rendering APIs for Node.js
- Use underscore instead of `:` IDs generated by useId

### All Changes

#### React

- `<Activity />` was developed over many years, starting before `ClassComponent.setState` (@acdlite @sebmarkbage and many others)
- Stringify context as "SomeContext" instead of "SomeContext.Provider" (@kassens [#33507](https://github.com/facebook/react/pull/33507))
- Include stack of cause of React instrumentation errors with `%o` placeholder (@eps1lon [#34198](https://github.com/facebook/react/pull/34198))
- Fix infinite `useDeferredValue` loop in popstate event (@acdlite [#32821](https://github.com/facebook/react/pull/32821))
- Fix a bug when an initial value was passed to `useDeferredValue` (@acdlite [#34376](https://github.com/facebook/react/pull/34376))
- Fix a crash when submitting forms with Client Actions (@sebmarkbage [#33055](https://github.com/facebook/react/pull/33055))
- Hide/unhide the content of dehydrated suspense boundaries if they resuspend (@sebmarkbage [#32900](https://github.com/facebook/react/pull/32900))
- Avoid stack overflow on wide trees during Hot Reload (@sophiebits [#34145](https://github.com/facebook/react/pull/34145))
- Improve Owner and Component stacks in various places (@sebmarkbage, @eps1lon: [#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))
- Add `cacheSignal` (@sebmarkbage [#33557](https://github.com/facebook/react/pull/33557))

#### React DOM

- Block on Suspensey Fonts during reveal of server-side-rendered content (@sebmarkbage [#33342](https://github.com/facebook/react/pull/33342))
- Use underscore instead of `:` for IDs generated by `useId` (@sebmarkbage, @eps1lon: [#32001](https://github.com/facebook/react/pull/32001), [https://github.com/facebook/react/pull/33342](https://github.com/facebook/react/pull/33342)[#33099](https://github.com/facebook/react/pull/33099), [#33422](https://github.com/facebook/react/pull/33422))
- Stop warning when ARIA 1.3 attributes are used (@Abdul-Omira [#34264](https://github.com/facebook/react/pull/34264))
- Allow `nonce` to be used on hoistable styles (@Andarist [#32461](https://github.com/facebook/react/pull/32461))
- Warn for using a React owned node as a Container if it also has text content (@sebmarkbage [#32774](https://github.com/facebook/react/pull/32774))
- s/HTML/text for for error messages if text hydration mismatches (@rickhanlonii [#32763](https://github.com/facebook/react/pull/32763))
- Fix a bug with `React.use` inside `React.lazy`\-ed Component (@hi-ogawa [#33941](https://github.com/facebook/react/pull/33941))
- Enable the `progressiveChunkSize` option for server-side-rendering APIs (@sebmarkbage [#33027](https://github.com/facebook/react/pull/33027))
- Fix a bug with deeply nested Suspense inside Suspense fallback when server-side-rendering (@gnoff [#33467](https://github.com/facebook/react/pull/33467))
- Avoid hanging when suspending after aborting while rendering (@gnoff [#34192](https://github.com/facebook/react/pull/34192))
- Add Node Web Streams to server-side-rendering APIs for Node.js (@sebmarkbage [#33475](https://github.com/facebook/react/pull/33475))

#### React Server Components

- Preload `<img>` and `<link>` using hints before they're rendered (@sebmarkbage [#34604](https://github.com/facebook/react/pull/34604))
- Log error if production elements are rendered during development (@eps1lon [#34189](https://github.com/facebook/react/pull/34189))
- Fix a bug when returning a Temporary reference (e.g. a Client Reference) from Server Functions (@sebmarkbage [#34084](https://github.com/facebook/react/pull/34084), @denk0403 [#33761](https://github.com/facebook/react/pull/33761))
- Pass line/column to `filterStackFrame` (@eps1lon [#33707](https://github.com/facebook/react/pull/33707))
- Support Async Modules in Turbopack Server References (@lubieowoce [#34531](https://github.com/facebook/react/pull/34531))
- Add support for .mjs file extension in Webpack (@jennyscript [#33028](https://github.com/facebook/react/pull/33028))
- Fix a wrong missing key warning (@unstubbable [#34350](https://github.com/facebook/react/pull/34350))
- Make console log resolve in predictable order (@sebmarkbage [#33665](https://github.com/facebook/react/pull/33665))

#### React Reconciler

- [createContainer](https://github.com/facebook/react/blob/v19.2.0/packages/react-reconciler/src/ReactFiberReconciler.js#L255-L261) and [createHydrationContainer](https://github.com/facebook/react/blob/v19.2.0/packages/react-reconciler/src/ReactFiberReconciler.js#L305-L312) had their parameter order adjusted after `on*` handlers to account for upcoming experimental APIs

## 19.1.1 (July 28, 2025)

### React
Expand Down
20 changes: 10 additions & 10 deletions ReactVersions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@
//
// The @latest channel uses the version as-is, e.g.:
//
// 19.2.0
// 19.3.0
//
// The @canary channel appends additional information, with the scheme
// <version>-<label>-<commit_sha>, e.g.:
//
// 19.2.0-canary-a1c2d3e4
// 19.3.0-canary-a1c2d3e4
//
// The @experimental channel doesn't include a version, only a date and a sha, e.g.:
//
// 0.0.0-experimental-241c4467e-20200129

const ReactVersion = '19.2.0';
const ReactVersion = '19.3.0';

// The label used by the @canary channel. Represents the upcoming release's
// stability. Most of the time, this will be "canary", but we may temporarily
Expand All @@ -33,21 +33,21 @@ const canaryChannelLabel = 'canary';
const rcNumber = 0;

const stablePackages = {
'eslint-plugin-react-hooks': '6.1.0',
'jest-react': '0.17.0',
'eslint-plugin-react-hooks': '6.2.0',
'jest-react': '0.18.0',
react: ReactVersion,
'react-art': ReactVersion,
'react-dom': ReactVersion,
'react-server-dom-webpack': ReactVersion,
'react-server-dom-turbopack': ReactVersion,
'react-server-dom-parcel': ReactVersion,
'react-is': ReactVersion,
'react-reconciler': '0.33.0',
'react-refresh': '0.18.0',
'react-reconciler': '0.34.0',
'react-refresh': '0.19.0',
'react-test-renderer': ReactVersion,
'use-subscription': '1.12.0',
'use-sync-external-store': '1.6.0',
scheduler: '0.27.0',
'use-subscription': '1.13.0',
'use-sync-external-store': '1.7.0',
scheduler: '0.28.0',
};

// These packages do not exist in the @canary or @latest channel, only
Expand Down
15 changes: 15 additions & 0 deletions packages/eslint-plugin-react-hooks/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
## 6.1.0

**Note:** Version 6.0.0 was mistakenly released and immediately deprecated and untagged on npm. This is the first official 6.x major release and includes breaking changes.

- **Breaking:** Require Node.js 18 or newer. ([@michaelfaith](https://github.com/michaelfaith) in [#32458](https://github.com/facebook/react/pull/32458))
- **Breaking:** Flat config is now the default `recommended` preset. Legacy config moved to `recommended-legacy`. ([@michaelfaith](https://github.com/michaelfaith) in [#32457](https://github.com/facebook/react/pull/32457))
- **New Violations:** Disallow calling `use` within try/catch blocks. ([@poteto](https://github.com/poteto) in [#34040](https://github.com/facebook/react/pull/34040))
- **New Violations:** Disallow calling `useEffectEvent` functions in arbitrary closures. ([@jbrown215](https://github.com/jbrown215) in [#33544](https://github.com/facebook/react/pull/33544))
- Handle `React.useEffect` in addition to `useEffect` in rules-of-hooks. ([@Ayc0](https://github.com/Ayc0) in [#34076](https://github.com/facebook/react/pull/34076))
- Added `react-hooks` settings config option that to accept `additionalEffectHooks` that are used across exhaustive-deps and rules-of-hooks rules. ([@jbrown215](https://github.com/jbrown215)) in [#34497](https://github.com/facebook/react/pull/34497)

## 6.0.0

Accidentally released. See 6.1.0 for the actual changes.

## 5.2.0

- Support flat config ([@michaelfaith](https://github.com/michaelfaith) in [#30774](https://github.com/facebook/react/pull/30774))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1637,17 +1637,32 @@ const allTests = {
const onClick = useEffectEvent(() => {
showNotification(theme);
});
// error message 1
const onClick2 = () => { onClick() };
// error message 2
const onClick3 = useCallback(() => onClick(), []);
// error message 3
const onClick4 = onClick;
return <>
{/** error message 4 */}
<Child onClick={onClick}></Child>
<Child onClick={onClick2}></Child>
<Child onClick={onClick3}></Child>
</>;
}
`,
// Explicitly test error messages here for various cases
errors: [
useEffectEventError('onClick', true),
useEffectEventError('onClick', true),
`\`onClick\` is a function created with React Hook "useEffectEvent", and can only be called from ` +
'Effects and Effect Events in the same component.',
`\`onClick\` is a function created with React Hook "useEffectEvent", and can only be called from ` +
'Effects and Effect Events in the same component.',
`\`onClick\` is a function created with React Hook "useEffectEvent", and can only be called from ` +
`Effects and Effect Events in the same component. ` +
`It cannot be assigned to a variable or passed down.`,
`\`onClick\` is a function created with React Hook "useEffectEvent", and can only be called from ` +
`Effects and Effect Events in the same component. ` +
`It cannot be assigned to a variable or passed down.`,
],
},
],
Expand Down Expand Up @@ -1714,7 +1729,8 @@ function useEffectEventError(fn, called) {
return {
message:
`\`${fn}\` is a function created with React Hook "useEffectEvent", and can only be called from ` +
`the same component.${called ? '' : ' They cannot be assigned to variables or passed down.'}`,
'Effects and Effect Events in the same component.' +
(called ? '' : ' It cannot be assigned to a variable or passed down.'),
};
}

Expand Down
4 changes: 4 additions & 0 deletions packages/eslint-plugin-react-hooks/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@
import type {Linter, Rule} from 'eslint';

import ExhaustiveDeps from './rules/ExhaustiveDeps';
import {allRules} from './shared/ReactCompiler';
import RulesOfHooks from './rules/RulesOfHooks';

// All rules
const rules = {
'exhaustive-deps': ExhaustiveDeps,
'rules-of-hooks': RulesOfHooks,
...Object.fromEntries(
Object.entries(allRules).map(([name, config]) => [name, config.rule]),
),
} satisfies Record<string, Rule.RuleModule>;

// Config rules
Expand Down
22 changes: 14 additions & 8 deletions packages/eslint-plugin-react-hooks/src/rules/RulesOfHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,19 @@ function isEffectIdentifier(node: Node, additionalHooks?: RegExp): boolean {

return false;
}

function isUseEffectEventIdentifier(node: Node): boolean {
return node.type === 'Identifier' && node.name === 'useEffectEvent';
}

function useEffectEventError(fn: string, called: boolean): string {
return (
`\`${fn}\` is a function created with React Hook "useEffectEvent", and can only be called from ` +
'Effects and Effect Events in the same component.' +
(called ? '' : ' It cannot be assigned to a variable or passed down.')
);
}

function isUseIdentifier(node: Node): boolean {
return isReactFunction(node, 'use');
}
Expand Down Expand Up @@ -769,14 +778,11 @@ const rule = {
// This identifier resolves to a useEffectEvent function, but isn't being referenced in an
// effect or another event function. It isn't being called either.
if (lastEffect == null && useEffectEventFunctions.has(node)) {
const message =
`\`${getSourceCode().getText(
node,
)}\` is a function created with React Hook "useEffectEvent", and can only be called from ` +
'the same component.' +
(node.parent.type === 'CallExpression'
? ''
: ' They cannot be assigned to variables or passed down.');
const message = useEffectEventError(
getSourceCode().getText(node),
node.parent.type === 'CallExpression',
);

context.report({
node,
message,
Expand Down
6 changes: 3 additions & 3 deletions packages/react-art/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "react-art",
"description": "React ART is a JavaScript library for drawing vector graphics using React. It provides declarative and reactive bindings to the ART library. Using the same declarative API you can render the output to either Canvas, SVG or VML (IE8).",
"version": "19.2.0",
"version": "19.3.0",
"main": "index.js",
"repository": {
"type": "git",
Expand All @@ -24,10 +24,10 @@
"dependencies": {
"art": "^0.10.1",
"create-react-class": "^15.6.2",
"scheduler": "^0.26.0"
"scheduler": "^0.28.0"
},
"peerDependencies": {
"react": "^19.2.0"
"react": "^19.3.0"
},
"files": [
"LICENSE",
Expand Down
2 changes: 1 addition & 1 deletion packages/react-dom-bindings/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "react-dom-bindings",
"description": "React implementation details for react-dom.",
"version": "19.2.0",
"version": "19.3.0",
"private": true,
"main": "index.js",
"repository": {
Expand Down
6 changes: 3 additions & 3 deletions packages/react-dom/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-dom",
"version": "19.2.0",
"version": "19.3.0",
"description": "React package for working with the DOM.",
"main": "index.js",
"repository": {
Expand All @@ -17,10 +17,10 @@
},
"homepage": "https://react.dev/",
"dependencies": {
"scheduler": "^0.26.0"
"scheduler": "^0.28.0"
},
"peerDependencies": {
"react": "^19.2.0"
"react": "^19.3.0"
},
"files": [
"LICENSE",
Expand Down
2 changes: 1 addition & 1 deletion packages/react-is/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-is",
"version": "19.2.0",
"version": "19.3.0",
"description": "Brand checking of React Elements.",
"main": "index.js",
"sideEffects": false,
Expand Down
2 changes: 1 addition & 1 deletion packages/react-markup/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-markup",
"version": "19.2.0",
"version": "19.3.0",
"description": "React package generating embedded markup such as e-mails with support for Server Components.",
"main": "index.js",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-native-renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"directory": "packages/react-native-renderer"
},
"dependencies": {
"scheduler": "^0.26.0"
"scheduler": "^0.28.0"
},
"peerDependencies": {
"react": "^18.0.0"
Expand Down
6 changes: 3 additions & 3 deletions packages/react-reconciler/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "react-reconciler",
"description": "React package for creating custom renderers.",
"version": "0.33.0",
"version": "0.34.0",
"keywords": [
"react"
],
Expand All @@ -26,9 +26,9 @@
"node": ">=0.10.0"
},
"peerDependencies": {
"react": "^19.2.0"
"react": "^19.3.0"
},
"dependencies": {
"scheduler": "^0.26.0"
"scheduler": "^0.28.0"
}
}
2 changes: 1 addition & 1 deletion packages/react-refresh/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"keywords": [
"react"
],
"version": "0.18.0",
"version": "0.19.0",
"homepage": "https://react.dev/",
"bugs": "https://github.com/facebook/react/issues",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/react-server-dom-esm/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "react-server-dom-esm",
"description": "React Server Components bindings for DOM using ESM. This is intended to be integrated into meta-frameworks. It is not intended to be imported directly.",
"version": "19.2.0",
"version": "19.3.0",
"keywords": [
"react"
],
Expand Down
2 changes: 1 addition & 1 deletion packages/react-server-dom-fb/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"directory": "packages/react-server-dom-fb"
},
"dependencies": {
"scheduler": "^0.26.0"
"scheduler": "^0.28.0"
},
"peerDependencies": {
"react": "^18.0.0",
Expand Down
6 changes: 3 additions & 3 deletions packages/react-server-dom-parcel/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "react-server-dom-parcel",
"description": "React Server Components bindings for DOM using Parcel. This is intended to be integrated into meta-frameworks. It is not intended to be imported directly.",
"version": "19.2.0",
"version": "19.3.0",
"keywords": [
"react"
],
Expand Down Expand Up @@ -79,7 +79,7 @@
"node": ">=0.10.0"
},
"peerDependencies": {
"react": "^19.2.0",
"react-dom": "^19.2.0"
"react": "^19.3.0",
"react-dom": "^19.3.0"
}
}
Loading
Loading