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.
4 changes: 2 additions & 2 deletions src/components/MDX/Sandpack/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ root.render(
eject: 'react-scripts eject',
},
dependencies: {
react: '^19.1.0',
'react-dom': '^19.1.0',
react: '^19.2.0',
'react-dom': '^19.2.0',
'react-scripts': '^5.0.0',
},
},
Expand Down
4 changes: 2 additions & 2 deletions src/components/MDX/SandpackWithHTMLOutput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ export default function formatHTML(markup) {
const packageJSON = `
{
"dependencies": {
"react": "18.3.0-canary-6db7f4209-20231021",
"react-dom": "18.3.0-canary-6db7f4209-20231021",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-scripts": "^5.0.0",
"html-format": "^1.1.2"
},
Expand Down
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).
>>>>>>> 996ef72c1a9f7ecc003588a897be85fc647393c3

</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 } from "react"; import Details from "./Details"; import Home from "./Home"; import { useRouter } from "./router"; import { unstable_Activity, Activity as ActivityStable} from 'react'; let Activity = ActivityStable ?? unstable_Activity;

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, use } from "react"; import Details from "./Details"; import Home from "./Home"; import { useRouter } from "./router"; import {fetchVideos} from './data'; import { unstable_Activity, Activity as ActivityStable} from 'react'; let Activity = ActivityStable ?? unstable_Activity;

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
8 changes: 6 additions & 2 deletions src/content/learn/escape-hatches.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,13 +312,17 @@ React 提供了检查工具规则来检查是否正确地指定了 Effect 的依

## 将事件从 Effect 中分开 {/*separating-events-from-effects*/}

<<<<<<< HEAD
<Wip>

本节描述了一个在稳定版本的 React 中 **尚未发布** 的实验性 API。

</Wip>

事件处理程序仅在再次执行相同的交互时重新运行。与事件处理程序不同,如果 Effect 读取的任何值(如 props 或 state)与上次渲染期间不同,则会重新同步。有时,需要混合两种行为:Effect 重新运行以响应某些值而不是其他值。
=======
Event handlers only re-run when you perform the same interaction again. Unlike event handlers, Effects re-synchronize if any of the values they read, like props or state, are different than during last render. Sometimes, you want a mix of both behaviors: an Effect that re-runs in response to some values but not others.
>>>>>>> 996ef72c1a9f7ecc003588a897be85fc647393c3

Effect 中的所有代码都是 **响应式的**。如果它读取的某些响应式的值由于重新渲染而发生变化,它将再次运行。例如,如果 `roomId` 或 `theme` 发生变化,这个 Effect 将重新连接到聊天:

Expand Down Expand Up @@ -455,8 +459,8 @@ label { display: block; margin-top: 10px; }
```json package.json hidden
{
"dependencies": {
"react": "canary",
"react-dom": "canary",
"react": "latest",
"react-dom": "latest",
"react-scripts": "latest",
"toastify-js": "1.12.0"
},
Expand Down
44 changes: 8 additions & 36 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`:
>>>>>>> 996ef72c1a9f7ecc003588a897be85fc647393c3

```js {3,10-12}
function ChatRoom({ roomId }) {
Expand Down Expand Up @@ -1260,22 +1264,6 @@ Effect 中是否有一行代码不应该是响应式的?如何将非响应式

<Sandpack>

```json package.json hidden
{
"dependencies": {
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
```

```js
import { useState, useEffect, useRef } from 'react';
import { useEffectEvent } from 'react';
Expand Down Expand Up @@ -1387,22 +1375,6 @@ Effect 需要读取 `duration` 的最新值,但你不希望它对 `duration`

<Sandpack>

```json package.json hidden
{
"dependencies": {
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
```

```js
import { useState, useEffect, useRef } from 'react';
import { FadeInAnimation } from './animation.js';
Expand Down Expand Up @@ -1826,8 +1798,8 @@ label, button { display: block; margin-bottom: 5px; }
```json package.json hidden
{
"dependencies": {
"react": "canary",
"react-dom": "canary",
"react": "latest",
"react-dom": "latest",
"react-scripts": "latest",
"toastify-js": "1.12.0"
},
Expand Down Expand Up @@ -2121,8 +2093,8 @@ export default function ChatRoom({ roomId, isEncrypted, onMessage }) { // Reacti
```json package.json hidden
{
"dependencies": {
"react": "canary",
"react-dom": "canary",
"react": "latest",
"react-dom": "latest",
"react-scripts": "latest",
"toastify-js": "1.12.0"
},
Expand Down
56 changes: 6 additions & 50 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:
>>>>>>> 996ef72c1a9f7ecc003588a897be85fc647393c3

```js {9-11}
export function useChatRoom({ serverUrl, roomId }) {
Expand Down Expand Up @@ -1072,8 +1076,8 @@ export function showNotification(message, theme = 'dark') {
```json package.json hidden
{
"dependencies": {
"react": "canary",
"react-dom": "canary",
"react": "latest",
"react-dom": "latest",
"react-scripts": "latest",
"toastify-js": "1.12.0"
},
Expand Down Expand Up @@ -1718,22 +1722,6 @@ html, body { min-height: 300px; }
}
```

```json package.json hidden
{
"dependencies": {
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
```

</Sandpack>

但是 **没有必要** 这样做。和常规函数一样,最终是由你决定在哪里划分代码不同部分之间的边界。你也可以采取不一样的方法。把大部分必要的逻辑移入一个 [JavaScript 类](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes),而不是把逻辑保留在 Effect 中:
Expand Down Expand Up @@ -2207,22 +2195,6 @@ export function useInterval(onTick, delay) {

<Sandpack>

```json package.json hidden
{
"dependencies": {
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
```

```js
import { useCounter } from './useCounter.js';
import { useInterval } from './useInterval.js';
Expand Down Expand Up @@ -2278,22 +2250,6 @@ export function useInterval(onTick, delay) {

<Sandpack>

```json package.json hidden
{
"dependencies": {
"react": "canary",
"react-dom": "canary",
"react-scripts": "latest"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
```


```js
import { useCounter } from './useCounter.js';
Expand Down
Loading
Loading