Skip to content
Open
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,17 @@ description: 在 React Labs 系列文章中,我们会介绍正在积极研究

<Note>

<<<<<<< HEAD
React Conf 2025 将于 10 月 7-8 日在内华达州亨德森举行!

我们正在寻找演讲者,帮助我们创建关于本文所涵盖功能的演讲。如果你有兴趣在 ReactConf 上发言,[请在此申请](https://forms.reform.app/react-conf/call-for-speakers/)(无需提交演讲提案)。

有关门票、免费直播、赞助等更多信息,请查看 [React Conf 网站](https://conf.react.dev)。
=======
React Conf 2025 is scheduled for October 7–8 in Henderson, Nevada!

Watch the livestream on [the React Conf website](https://conf.react.dev).
>>>>>>> 0a803f61d84723e87f2481f31ea77da9606664c9

</Note>

Expand Down Expand Up @@ -11544,7 +11550,7 @@ function App() {
<Sandpack>

```js src/App.js
import { unstable_ViewTransition as ViewTransition, unstable_Activity as Activity } from "react"; import Details from "./Details"; import Home from "./Home"; import { useRouter } from "./router";
import { unstable_ViewTransition as ViewTransition, Activity } from "react"; import Details from "./Details"; import Home from "./Home"; import { useRouter } from "./router";

export default function App() {
const { url } = useRouter();
Expand Down Expand Up @@ -12881,7 +12887,7 @@ With this update, if the content on the next page has time to pre-render, it wil
<Sandpack>

```js src/App.js
import { unstable_ViewTransition as ViewTransition, unstable_Activity as Activity, use } from "react"; import Details from "./Details"; import Home from "./Home"; import { useRouter } from "./router"; import {fetchVideos} from './data'
import { unstable_ViewTransition as ViewTransition, Activity, use } from "react"; import Details from "./Details"; import Home from "./Home"; import { useRouter } from "./router"; import {fetchVideos} from './data'

export default function App() {
const { url } = useRouter();
Expand Down
339 changes: 339 additions & 0 deletions src/content/blog/2025/10/01/react-19-2.md

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions src/content/blog/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ title: React Blog

<div className="sm:-mx-5 flex flex-col gap-5 mt-12">

<BlogCard title="React 19.2" date="October 1, 2025" url="/blog/2025/10/01/react-19-2">

React 19.2 adds new features like Activity, React Performance Tracks, useEffectEvent, and more. In this post ...

</BlogCard>

<BlogCard title="React Labs: View Transitions, Activity, and more" date="April 23, 2025" url="/blog/2025/04/23/react-labs-view-transitions-activity-and-more">

In React Labs posts, we write about projects in active research and development. In this post, we're sharing two new experimental features that are ready to try today, and sharing other areas we're working on now ...
Expand Down
4 changes: 4 additions & 0 deletions src/content/learn/removing-effect-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,7 @@ function ChatRoom({ roomId }) {

### 你想读取一个值而不对其变化做出“反应”吗? {/*do-you-want-to-read-a-value-without-reacting-to-its-changes*/}

<<<<<<< HEAD
<Canary>

**`useEffectEvent` API 当前仅在 React Canary 和 实验发行版中可用**。
Expand All @@ -619,6 +620,9 @@ function ChatRoom({ roomId }) {
</Canary>

假设你希望在用户收到新消息时播放声音,`isMuted` 为 `true` 除外:
=======
Suppose that you want to play a sound when the user receives a new message unless `isMuted` is `true`:
>>>>>>> 0a803f61d84723e87f2481f31ea77da9606664c9

```js {3,10-12}
function ChatRoom({ roomId }) {
Expand Down
4 changes: 4 additions & 0 deletions src/content/learn/reusing-logic-with-custom-hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,7 @@ export default function ChatRoom({ roomId }) {

### 把事件处理函数传到自定义 Hook 中 {/*passing-event-handlers-to-custom-hooks*/}

<<<<<<< HEAD
<Canary>

**`useEffectEvent` API 当前仅在 React Canary 和 实验发行版中可用**。
Expand All @@ -846,6 +847,9 @@ export default function ChatRoom({ roomId }) {
</Canary>

当你在更多组件中使用 `useChatRoom` 时,你可能希望组件能定制它的行为。例如现在 Hook 内部收到消息的处理逻辑是硬编码:
=======
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:
>>>>>>> 0a803f61d84723e87f2481f31ea77da9606664c9

```js {9-11}
export function useChatRoom({ serverUrl, roomId }) {
Expand Down
16 changes: 16 additions & 0 deletions src/content/learn/separating-events-from-effects.md
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ label { display: block; margin-top: 10px; }

### 声明一个 Effect Event {/*declaring-an-effect-event*/}

<<<<<<< HEAD
<Canary>

**`useEffectEvent` API 当前仅在 React Canary 和 实验发行版中可用**。
Expand All @@ -409,6 +410,9 @@ label { display: block; margin-top: 10px; }
</Canary>

使用 [`useEffectEvent`](/reference/react/useEffectEvent) 这个特殊的 Hook 从 Effect 中提取非响应式逻辑:
=======
Use a special Hook called [`useEffectEvent`](/reference/react/useEffectEvent) to extract this non-reactive logic out of your Effect:
>>>>>>> 0a803f61d84723e87f2481f31ea77da9606664c9

```js {1,4-6}
import { useEffect, useEffectEvent } from 'react';
Expand Down Expand Up @@ -580,6 +584,7 @@ label { display: block; margin-top: 10px; }

### 使用 Effect Event 读取最新的 props 和 state {/*reading-latest-props-and-state-with-effect-events*/}

<<<<<<< HEAD
<Canary>

**`useEffectEvent` API 当前仅在 React Canary 和 实验发行版中可用**。
Expand All @@ -589,6 +594,9 @@ label { display: block; margin-top: 10px; }
</Canary>

Effect Event 可以修复之前许多你可能试图抑制依赖项检查工具的地方。
=======
Effect Events let you fix many patterns where you might be tempted to suppress the dependency linter.
>>>>>>> 0a803f61d84723e87f2481f31ea77da9606664c9

例如,假设你有一个记录页面访问的 Effect:

Expand Down Expand Up @@ -729,7 +737,11 @@ function Page({ url }) {
}
```

<<<<<<< HEAD
等 `useEffectEvent` 成为 React 稳定部分后,我们会推荐 **永远不要抑制代码检查工具**。
=======
We recommend **never suppressing the linter**.
>>>>>>> 0a803f61d84723e87f2481f31ea77da9606664c9

抑制规则的第一个缺点是当 Effect 需要对一个已经在代码中出现过的新响应式依赖项做出“响应”时,React 不会再发出警告。在稍早之前的示例中,你将 `url` 添加为依赖项,**是因为** React 提醒你去做这件事。如果禁用代码检查,你未来将不会再收到任何关于 Effect 修改的提醒。这引起了 bug。

Expand Down Expand Up @@ -882,6 +894,7 @@ body {

### Effect Event 的局限性 {/*limitations-of-effect-events*/}

<<<<<<< HEAD
<Canary>

**`useEffectEvent` API 当前仅在 React Canary 和 实验发行版中可用**。
Expand All @@ -891,6 +904,9 @@ body {
</Canary>

Effect Event 的局限性在于你如何使用他们:
=======
Effect Events are very limited in how you can use them:
>>>>>>> 0a803f61d84723e87f2481f31ea77da9606664c9

* **只在 Effect 内部调用他们**。
* **永远不要把他们传给其他的组件或者 Hook**。
Expand Down
152 changes: 152 additions & 0 deletions src/content/reference/dev-tools/react-performance-tracks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
---
title: React Performance tracks
---

<Intro>

React Performance tracks are specialized custom entries that appear on the Performance panel's timeline in your browser developer tools.

</Intro>

These tracks are designed to provide developers with comprehensive insights into their React application's performance by visualizing React-specific events and metrics alongside other critical data sources such as network requests, JavaScript execution, and event loop activity, all synchronized on a unified timeline within the Performance panel for a complete understanding of application behavior.

<div style={{display: 'flex', justifyContent: 'center', marginBottom: '1rem'}}>
<img className="w-full light-image" src="/images/docs/performance-tracks/overview.png" alt="React Performance Tracks" />
<img className="w-full dark-image" src="/images/docs/performance-tracks/overview.dark.png" alt="React Performance Tracks" />
</div>

<InlineToc />

---

## Usage {/*usage*/}

React Performance tracks are only available in development and profiling builds of React:

- **Development**: enabled by default.
- **Profiling**: you can either wrap a subtree that you want to instrument with [`<Profiler>`](/reference/react/Profiler) component or have [React Developer Tools extension](/learn/react-developer-tools) enabled. Tracks specific to React Server Components are not enabled in profiling builds.

If enabled, tracks should appear automatically in the traces you record with the Performance panel of browsers that provide [extensibility APIs](https://developer.chrome.com/docs/devtools/performance/extension).

<Pitfall>

The profiling instrumentation that powers React Performance tracks adds some additional overhead, so it is disabled in production builds by default.
Server Components and Server Requests tracks are only available in development builds.

</Pitfall>

---

## Tracks {/*tracks*/}

### Scheduler {/*scheduler*/}

The Scheduler is an internal React concept used for managing tasks with different priorities. This track consists of 4 subtracks, each representing work of a specific priority:

- **Blocking** - The synchronous updates, which could've been initiated by user interactions.
- **Transition** - Non-blocking work that happens in the background, usually initiated via [`startTransition`](/reference/react/startTransition).
- **Suspense** - Work related to Suspense boundaries, such as displaying fallbacks or revealing content.
- **Idle** - The lowest priority work that is done when there are no other tasks with higher priority.

<div style={{display: 'flex', justifyContent: 'center', marginBottom: '1rem'}}>
<img className="w-full light-image" src="/images/docs/performance-tracks/scheduler.png" alt="Scheduler track" />
<img className="w-full dark-image" src="/images/docs/performance-tracks/scheduler.dark.png" alt="Scheduler track" />
</div>

#### Renders {/*renders*/}

Every render pass consists of multiple phases that you can see on a timeline:

- **Update** - this is what caused a new render pass.
- **Render** - React renders the updated subtree by calling render functions of components. You can see the rendered components subtree on [Components track](#components), which follows the same color scheme.
- **Commit** - After rendering components, React will submit the changes to the DOM and run layout effects, like [`useLayoutEffect`](/reference/react/useLayoutEffect).
- **Remaining Effects** - React runs passive effects of a rendered subtree. This usually happens after the paint, and this is when React runs hooks like [`useEffect`](/reference/react/useEffect). One known exception is user interactions, like clicks, or other discrete events. In this scenario, this phase could run before the paint.

<div style={{display: 'flex', justifyContent: 'center', marginBottom: '1rem'}}>
<img className="w-full light-image" src="/images/docs/performance-tracks/scheduler-update.png" alt="Scheduler track: updates" />
<img className="w-full dark-image" src="/images/docs/performance-tracks/scheduler-update.dark.png" alt="Scheduler track: updates" />
</div>

[Learn more about renders and commits](/learn/render-and-commit).

#### Cascading updates {/*cascading-updates*/}

Cascading updates is one of the patterns for performance regressions. If an update was scheduled during a render pass, React could discard completed work and start a new pass.

In development builds, React can show you which Component scheduled a new update. This includes both general updates and cascading ones. You can see the enhanced stack trace by clicking on the "Cascading update" entry, which should also display the name of the method that scheduled an update.

<div style={{display: 'flex', justifyContent: 'center', marginBottom: '1rem'}}>
<img className="w-full light-image" src="/images/docs/performance-tracks/scheduler-cascading-update.png" alt="Scheduler track: cascading updates" />
<img className="w-full dark-image" src="/images/docs/performance-tracks/scheduler-cascading-update.dark.png" alt="Scheduler track: cascading updates" />
</div>

[Learn more about Effects](/learn/you-might-not-need-an-effect).

### Components {/*components*/}

The Components track visualizes the durations of React components. They are displayed as a flamegraph, where each entry represents the duration of the corresponding component render and all its descendant children components.

<div style={{display: 'flex', justifyContent: 'center', marginBottom: '1rem'}}>
<img className="w-full light-image" src="/images/docs/performance-tracks/components-render.png" alt="Components track: render durations" />
<img className="w-full dark-image" src="/images/docs/performance-tracks/components-render.dark.png" alt="Components track: render durations" />
</div>

Similar to render durations, effect durations are also represented as a flamegraph, but with a different color scheme that aligns with the corresponding phase on the Scheduler track.

<div style={{display: 'flex', justifyContent: 'center', marginBottom: '1rem'}}>
<img className="w-full light-image" src="/images/docs/performance-tracks/components-effects.png" alt="Components track: effects durations" />
<img className="w-full dark-image" src="/images/docs/performance-tracks/components-effects.dark.png" alt="Components track: effects durations" />
</div>

<Note>

Unlike renders, not all effects are shown on the Components track by default.

To maintain performance and prevent UI clutter, React will only display those effects, which had a duration of 0.05ms or longer, or triggered an update.

</Note>

Additional events may be displayed during the render and effects phases:

- <span style={{padding: '0.125rem 0.25rem', backgroundColor: '#facc15', color: '#1f1f1fff'}}>Mount</span> - A corresponding subtree of component renders or effects was mounted.
- <span style={{padding: '0.125rem 0.25rem', backgroundColor: '#facc15', color: '#1f1f1fff'}}>Unmount</span> - A corresponding subtree of component renders or effects was unmounted.
- <span style={{padding: '0.125rem 0.25rem', backgroundColor: '#facc15', color: '#1f1f1fff'}}>Reconnect</span> - Similar to Mount, but limited to cases when [`<Activity>`](/reference/react/Activity) is used.
- <span style={{padding: '0.125rem 0.25rem', backgroundColor: '#facc15', color: '#1f1f1fff'}}>Disconnect</span> - Similar to Unmount, but limited to cases when [`<Activity>`](/reference/react/Activity) is used.

#### Changed props {/*changed-props*/}

In development builds, when you click on a component render entry, you can inspect potential changes in props. You can use this information to identify unnecessary renders.

<div style={{display: 'flex', justifyContent: 'center', marginBottom: '1rem'}}>
<img className="w-full light-image" src="/images/docs/performance-tracks/changed-props.png" alt="Components track: changed props" />
<img className="w-full dark-image" src="/images/docs/performance-tracks/changed-props.dark.png" alt="Components track: changed props" />
</div>

### Server {/*server*/}

<div style={{display: 'flex', justifyContent: 'center', marginBottom: '1rem'}}>
<img className="w-full light-image" src="/images/docs/performance-tracks/server-overview.png" alt="React Server Performance Tracks" />
<img className="w-full dark-image" src="/images/docs/performance-tracks/server-overview.dark.png" alt="React Server Performance Tracks" />
</div>

#### Server Requests {/*server-requests*/}

The Server Requests track visualized all Promises that eventually end up in a React Server Component. This includes any `async` operations like calling `fetch` or async Node.js file operations.

React will try to combine Promises that are started from inside third-party code into a single span representing the the duration of the entire operation blocking 1st party code.
For example, a third party library method called `getUser` that calls `fetch` internally multiple times will be represented as a single span called `getUser`, instead of showing multiple `fetch` spans.

Clicking on spans will show you a stack trace of where the Promise was created as well as a view of the value that the Promise resolved to, if available.

Rejected Promises are displayed as red with their rejected value.

#### Server Components {/*server-components*/}

The Server Components tracks visualize the durations of React Server Components Promises they awaited. Timings are displayed as a flamegraph, where each entry represents the duration of the corresponding component render and all its descendant children components.

If you await a Promise, React will display duration of that Promise. To see all I/O operations, use the Server Requests track.

Different colors are used to indicate the duration of the component render. The darker the color, the longer the duration.

The Server Components track group will always contain a "Primary" track. If React is able to render Server Components concurrently, it will display addititional "Parallel" tracks.
If more than 8 Server Components are rendered concurrently, React will associate them with the last "Parallel" track instead of adding more tracks.
16 changes: 5 additions & 11 deletions src/content/reference/eslint-plugin-react-hooks/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@ version: rc

</Intro>

<RC>

These docs include rules available in the RC version of `eslint-plugin-react-hooks`.

You can try them by upgrading the lint plugin [to the most recent RC version](/learn/react-compiler/installation#eslint-integration).

</RC>

This plugin helps you catch violations of React's rules at build time, ensuring your components and hooks follow React's rules for correctness and performance. The lints cover both fundamental React patterns (exhaustive-deps and rules-of-hooks) and issues flagged by React Compiler. React Compiler diagnostics are automatically surfaced by this ESLint plugin, and can be used even if your app hasn't adopted the compiler yet.

<Note>
Expand All @@ -25,14 +17,16 @@ When the compiler reports a diagnostic, it means that the compiler was able to s
What this means for linting, is that you don’t need to fix all violations immediately. Address them at your own pace to gradually increase the number of optimized components.
</Note>

## Available Lints {/*available-lints*/}
## Recommended Rules {/*recommended*/}

These rules are available in the stable version of `eslint-plugin-react-hooks`:
These rules are included in the `recommended` preset `eslint-plugin-react-hooks`:

* [`exhaustive-deps`](/reference/eslint-plugin-react-hooks/lints/exhaustive-deps) - Validates that dependency arrays for React hooks contain all necessary dependencies
* [`rules-of-hooks`](/reference/eslint-plugin-react-hooks/lints/rules-of-hooks) - Validates that components and hooks follow the Rules of Hooks

These rules are available in the RC version of `eslint-plugin-react-hooks`:
## Additional Rules {/*additional-rules*/}

Starting in version 6.0, these rules are available to opt-in:

* [`component-hook-factories`](/reference/eslint-plugin-react-hooks/lints/component-hook-factories) - Validates higher order functions defining nested components or hooks
* [`config`](/reference/eslint-plugin-react-hooks/lints/config) - Validates the compiler configuration options
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
title: component-hook-factories
version: rc
---

<Intro>
Expand All @@ -9,13 +8,11 @@ Validates against higher order functions defining nested components or hooks. Co

</Intro>

<RC>
<Note>

This rule is available in the RC version of `eslint-plugin-react-hooks`.
This rule is available in `eslint-plugin-react-hooks` v6.

You can try it by upgrading the lint plugin [to the most recent RC version](/learn/react-compiler/installation#eslint-integration).

</RC>
</Note>

## Rule Details {/*rule-details*/}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ Validates the compiler [configuration options](/reference/react-compiler/configu

</Intro>

<RC>
<Note>

This rule is available in the RC version of `eslint-plugin-react-hooks`.
This rule is available in `eslint-plugin-react-hooks` v6.

You can try it by upgrading the lint plugin [to the most recent RC version](/learn/react-compiler/installation#eslint-integration).

</RC>
</Note>

## Rule Details {/*rule-details*/}

Expand Down
Loading
Loading