Skip to content

docs(en): merge reactjs.org/main into zh-hans.reactjs.org/main @ 6ead1fae #1695

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Apr 8, 2025
2 changes: 1 addition & 1 deletion postcss.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ module.exports = {
},
},
},
}
};
6 changes: 4 additions & 2 deletions public/js/jsfiddle-integration-babel.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

// Do not delete or move this file.
// Many fiddles reference it so we have to keep it here.
(function() {
(function () {
var tag = document.querySelector(
'script[type="application/javascript;version=1.7"]'
);
if (!tag || tag.textContent.indexOf('window.onload=function(){') !== -1) {
alert('Bad JSFiddle configuration, please fork the original React JSFiddle');
alert(
'Bad JSFiddle configuration, please fork the original React JSFiddle'
);
}
tag.setAttribute('type', 'text/babel');
tag.textContent = tag.textContent.replace(/^\/\/<!\[CDATA\[/, '');
Expand Down
6 changes: 4 additions & 2 deletions public/js/jsfiddle-integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

// Do not delete or move this file.
// Many fiddles reference it so we have to keep it here.
(function() {
(function () {
var tag = document.querySelector(
'script[type="application/javascript;version=1.7"]'
);
if (!tag || tag.textContent.indexOf('window.onload=function(){') !== -1) {
alert('Bad JSFiddle configuration, please fork the original React JSFiddle');
alert(
'Bad JSFiddle configuration, please fork the original React JSFiddle'
);
}
tag.setAttribute('type', 'text/jsx;harmony=true');
tag.textContent = tag.textContent.replace(/^\/\/<!\[CDATA\[/, '');
Expand Down
4 changes: 2 additions & 2 deletions src/components/MDX/Sandpack/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ root.render(
eject: 'react-scripts eject',
},
dependencies: {
react: '19.0.0-rc-3edc000d-20240926',
'react-dom': '19.0.0-rc-3edc000d-20240926',
react: '^19.1.0',
'react-dom': '^19.1.0',
'react-scripts': '^5.0.0',
},
},
Expand Down
3 changes: 2 additions & 1 deletion src/content/community/meetups.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Do you have a local React.js meetup? Add it here! (Please keep the list alphabet
* [Thessaloniki](https://www.meetup.com/Thessaloniki-ReactJS-Meetup/)

## India {/*india*/}
* [Ahmedabad](https://www.meetup.com/react-ahmedabad/)
* [Ahmedabad](https://reactahmedabad.dev/)
* [Bangalore (React)](https://www.meetup.com/ReactJS-Bangalore/)
* [Bangalore (React Native)](https://www.meetup.com/React-Native-Bangalore-Meetup)
* [Chennai](https://www.linkedin.com/company/chennaireact)
Expand Down Expand Up @@ -169,6 +169,7 @@ Do you have a local React.js meetup? Add it here! (Please keep the list alphabet
* [Cleveland, OH - ReactJS](https://www.meetup.com/Cleveland-React/)
* [Columbus, OH - ReactJS](https://www.meetup.com/ReactJS-Columbus-meetup/)
* [Dallas, TX - ReactJS](https://www.meetup.com/ReactDallas/)
* [Denver, CO - React Denver](https://reactdenver.com/)
* [Detroit, MI - Detroit React User Group](https://www.meetup.com/Detroit-React-User-Group/)
* [Indianapolis, IN - React.Indy](https://www.meetup.com/React-Indy)
* [Irvine, CA - ReactJS](https://www.meetup.com/ReactJS-OC/)
Expand Down
2 changes: 1 addition & 1 deletion src/content/learn/reusing-logic-with-custom-hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -1333,7 +1333,7 @@ export function useOnlineStatus() {

在上述示例中,`useOnlineStatus` 借助一组 [`useState`](/reference/react/useState) 和 [`useEffect`](/reference/react/useEffect) 实现。但这不是最好的解决方案。它有许多边界用例没有考虑到。例如,它认为当组件加载时,`isOnline` 已经为 `true`,但是如果网络已经离线的话这就是错误的。你可以使用浏览器的 [`navigator.onLine`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine) API 来检查,但是在生成初始 HTML 的服务端直接使用它是没用的。简而言之这段代码可以改进。

幸运的是,React 18 包含了一个叫做 [`useSyncExternalStore`](/reference/react/useSyncExternalStore) 的专用 API,它可以解决你所有这些问题。这里展示了如何利用这个新 API 来重写你的 `useOnlineStatus` Hook:
React 包含了一个叫做 [`useSyncExternalStore`](/reference/react/useSyncExternalStore) 的专用 API,它可以解决你所有这些问题。这里展示了如何利用这个新 API 来重写你的 `useOnlineStatus` Hook:

<Sandpack>

Expand Down
3 changes: 1 addition & 2 deletions src/content/reference/react/Component.md
Original file line number Diff line number Diff line change
Expand Up @@ -1273,7 +1273,7 @@ button { margin-left: 10px; }

要实现错误边界组件,你需要提供 [`static getDerivedStateFromError`](#static-getderivedstatefromerror),它允许你更新状态以响应错误并向用户显示错误消息。你还可以选择实现 [`componentDidCatch`](#componentdidcatch) 来添加一些额外的逻辑,例如将错误添加到分析服务。

<CanaryBadge /> With [`captureOwnerStack`](/reference/react/captureOwnerStack) you can include the Owner Stack during development.
With [`captureOwnerStack`](/reference/react/captureOwnerStack) you can include the Owner Stack during development.

```js {9-12,14-27}
import * as React from 'react';
Expand All @@ -1298,7 +1298,6 @@ class ErrorBoundary extends React.Component {
// 在 div 中(由 APP 创建)
// 在 App 中
info.componentStack,
// 仅在 react@canary 版本可用
// 警告:Owner Stack 在生产中不可用
React.captureOwnerStack(),
);
Expand Down
2 changes: 1 addition & 1 deletion src/content/reference/react/StrictMode.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ function App() {

<Note>

When `StrictMode` is enabled for a part of the app, React will only enable behaviors that are possible in production. For example, if `<StrictMode>` is not enabled at the root of the app, it will not [re-run Effects an extra time](#fixing-bugs-found-by-cleaning-up-and-re-attaching-dom-refs-in-development) on initial mount, since this would cause child effects to double fire without the parent effects, which cannot happen in production.
When `StrictMode` is enabled for a part of the app, React will only enable behaviors that are possible in production. For example, if `<StrictMode>` is not enabled at the root of the app, it will not [re-run Effects an extra time](#fixing-bugs-found-by-re-running-effects-in-development) on initial mount, since this would cause child effects to double fire without the parent effects, which cannot happen in production.

</Note>

Expand Down
48 changes: 0 additions & 48 deletions src/content/reference/react/captureOwnerStack.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,22 +120,6 @@ createRoot(document.createElement('div'), {
);
```

```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"
}
}
```

```html public/index.html hidden
<!DOCTYPE html>
<html lang="en">
Expand Down Expand Up @@ -351,22 +335,6 @@ const container = document.getElementById("root");
createRoot(container).render(<App />);
```

```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 src/App.js
function Component() {
return <button onClick={() => console.error('Some console error')}>Trigger console.error()</button>;
Expand Down Expand Up @@ -411,22 +379,6 @@ export default function App() {
}
```

```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>

### `captureOwnerStack` is not available {/*captureownerstack-is-not-available*/}
Expand Down
2 changes: 2 additions & 0 deletions src/content/reference/react/useId.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ function PasswordField() {

* `useId` **不应该被用来生成列表中的 key**。[key 应该由你的数据生成](/learn/rendering-lists#where-to-get-your-key)。

* `useId` currently cannot be used in [async Server Components](/reference/rsc/server-components#async-components-with-server-components).

---

## 用法 {/*usage*/}
Expand Down
22 changes: 11 additions & 11 deletions src/content/reference/react/useSyncExternalStore.md
Original file line number Diff line number Diff line change
Expand Up @@ -405,43 +405,43 @@ function getSnapshot() {

这里的 `subscribe` 函数是在组件 **内部** 定义的,所以它每次渲染都不同:

```js {4-7}
```js {2-5}
function ChatIndicator() {
const isOnline = useSyncExternalStore(subscribe, getSnapshot);

// 🚩 总是不同的函数,所以 React 每次重新渲染都会重新订阅
function subscribe() {
// ...
}

const isOnline = useSyncExternalStore(subscribe, getSnapshot);

// ...
}
```

如果重新渲染时你传一个不同的 `subscribe` 函数,React 会重新订阅你的 store。如果这造成了性能问题,因而你想避免重新订阅,就把 `subscribe` 函数移到外面:

```js {6-9}
function ChatIndicator() {
const isOnline = useSyncExternalStore(subscribe, getSnapshot);
```js {1-4}
// ✅ 总是相同的函数,所以 React 不需要重新订阅
function subscribe() {
// ...
}

// ✅ 总是相同的函数,所以 React 不需要重新订阅
function subscribe() {
function ChatIndicator() {
const isOnline = useSyncExternalStore(subscribe, getSnapshot);
// ...
}
```

或者,把 `subscribe` 包在 [`useCallback`](/reference/react/useCallback) 里面以便只在某些参数改变时重新订阅:

```js {4-8}
```js {2-5}
function ChatIndicator({ userId }) {
const isOnline = useSyncExternalStore(subscribe, getSnapshot);

// ✅ 只要 userId 不变,都是同一个函数
const subscribe = useCallback(() => {
// ...
}, [userId]);

const isOnline = useSyncExternalStore(subscribe, getSnapshot);

// ...
}
Expand Down