Skip to content

docs(en): merge reactjs.org/main into zh-hans.reactjs.org/main @ 5138e605 #1692

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

Closed
wants to merge 10 commits into from
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
4 changes: 4 additions & 0 deletions src/content/learn/build-a-react-app-from-scratch.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,11 @@ Rsbuild 内置了对 React 特性的支持,如快速刷新、JSX、TypeScript

#### React Native 的 Metro {/*react-native*/}

<<<<<<< HEAD
如果你从头开始使用 React Native,你将需要使用 [Metro](https://metrobundler.dev/), 这是 React Native 的 JavaScript 打包工具。Metro 支持 iOS 和 Android 等平台的打包,但与这里提到的工具相比,它缺少许多功能。除非你的项目需要 React Native 支持,否则我们建议从 Vite、Parcel 或 Rsbuild 开始。
=======
If you're starting from scratch with React Native you'll need to use [Metro](https://metrobundler.dev/), the JavaScript bundler for React Native. Metro supports bundling for platforms like iOS and Android, but lacks many features when compared to the tools here. We recommend starting with Vite, Parcel, or Rsbuild unless your project requires React Native support.
>>>>>>> 5138e605225b24d25701a1a1f68daa90499122a4

</Note>

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 @@ -1333,7 +1333,11 @@ 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 的服务端直接使用它是没用的。简而言之这段代码可以改进。

<<<<<<< HEAD
幸运的是,React 18 包含了一个叫做 [`useSyncExternalStore`](/reference/react/useSyncExternalStore) 的专用 API,它可以解决你所有这些问题。这里展示了如何利用这个新 API 来重写你的 `useOnlineStatus` Hook:
=======
React includes a dedicated API called [`useSyncExternalStore`](/reference/react/useSyncExternalStore) which takes care of all of these problems for you. Here is your `useOnlineStatus` Hook, rewritten to take advantage of this new API:
>>>>>>> 5138e605225b24d25701a1a1f68daa90499122a4

<Sandpack>

Expand Down
4 changes: 4 additions & 0 deletions src/content/learn/tutorial-tic-tac-toe.md
Original file line number Diff line number Diff line change
Expand Up @@ -2247,7 +2247,11 @@ body {

</Sandpack>

<<<<<<< HEAD
当你在传递给 `map` 的函数中遍历 `history` 数组时,`squares` 参数遍历 `history` 的每个元素,`move` 参数遍历每个数组索引:`0` 、`1`、`2`……(在大多数情况下,你需要数组元素,但要渲染落子列表,你只需要索引。)
=======
As you iterate through the `history` array inside the function you passed to `map`, the `squares` argument goes through each element of `history`, and the `move` argument goes through each array index: `0`, `1`, `2`, …. (In most cases, you'd need the actual array elements, but to render a list of moves you will only need indexes.)
>>>>>>> 5138e605225b24d25701a1a1f68daa90499122a4

对于井字棋游戏历史中的每一步,你创建一个列表项 `<li>`,其中包含一个按钮 `<button>`。该按钮有一个 `onClick` 处理程序,它调用一个名为 `jumpTo` 的函数(你尚未实现)。

Expand Down
6 changes: 5 additions & 1 deletion 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,8 +1298,12 @@ class ErrorBoundary extends React.Component {
// 在 div 中(由 APP 创建)
// 在 App 中
info.componentStack,
<<<<<<< HEAD
// 仅在 react@canary 版本可用
// 警告:Owner Stack 在生产中不可用
=======
// Warning: `captureOwnerStack` is not available in production.
>>>>>>> 5138e605225b24d25701a1a1f68daa90499122a4
React.captureOwnerStack(),
);
}
Expand Down
9 changes: 8 additions & 1 deletion src/content/reference/react/StrictMode.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,17 @@ root.render(

严格模式启用了以下仅在开发环境下有效的行为:

<<<<<<< HEAD
- 组件将 [重新渲染一次](#fixing-bugs-found-by-double-rendering-in-development) 以查找由于非纯渲染而引起的错误。
- 组件将 [重新运行一次 Effect](#fixing-bugs-found-by-re-running-effects-in-development) 以查找由于缺少 Effect 清理而引起的错误。
- 组件将 [额外重新运行一次 refs 回调](#fixing-bugs-found-by-re-running-ref-callbacks-in-development) 以查找由于缺少 ref 清理函数而引起的错误。
- 组件将被 [检查是否使用了已弃用的 API](#fixing-deprecation-warnings-enabled-by-strict-mode)。
=======
- Your components will [re-render an extra time](#fixing-bugs-found-by-double-rendering-in-development) to find bugs caused by impure rendering.
- Your components will [re-run Effects an extra time](#fixing-bugs-found-by-re-running-effects-in-development) to find bugs caused by missing Effect cleanup.
- Your components will [re-run ref callbacks an extra time](#fixing-bugs-found-by-re-running-ref-callbacks-in-development) to find bugs caused by missing ref cleanup.
- Your components will [be checked for usage of deprecated APIs.](#fixing-deprecation-warnings-enabled-by-strict-mode)
>>>>>>> 5138e605225b24d25701a1a1f68daa90499122a4

**所有这些检查仅在开发环境中进行,不会影响生产构建。**

Expand Down Expand Up @@ -124,7 +131,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
27 changes: 22 additions & 5 deletions src/content/reference/react/useSyncExternalStore.md
Original file line number Diff line number Diff line change
Expand Up @@ -405,43 +405,60 @@ function getSnapshot() {

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

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

// 🚩 总是不同的函数,所以 React 每次重新渲染都会重新订阅
=======
// 🚩 Always a different function, so React will resubscribe on every re-render
>>>>>>> 5138e605225b24d25701a1a1f68daa90499122a4
function subscribe() {
// ...
}

const isOnline = useSyncExternalStore(subscribe, getSnapshot);

// ...
}
```

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

```js {6-9}
function ChatIndicator() {
const isOnline = useSyncExternalStore(subscribe, getSnapshot);
```js {1-4}
// ✅ Always the same function, so React won't need to resubscribe
function subscribe() {
// ...
}

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

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

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

// ✅ 只要 userId 不变,都是同一个函数
=======
// ✅ Same function as long as userId doesn't change
>>>>>>> 5138e605225b24d25701a1a1f68daa90499122a4
const subscribe = useCallback(() => {
// ...
}, [userId]);

const isOnline = useSyncExternalStore(subscribe, getSnapshot);

// ...
}
Expand Down