Skip to content

Commit

Permalink
fix merge conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
loveloki committed Oct 1, 2024
1 parent adb21ea commit 27ca116
Show file tree
Hide file tree
Showing 12 changed files with 21 additions and 91 deletions.
4 changes: 0 additions & 4 deletions src/content/learn/synchronizing-with-effects.md
Original file line number Diff line number Diff line change
Expand Up @@ -627,11 +627,7 @@ React 有意在开发环境下重新挂载你的组件,来找到类似上例
### 管理非 React 小部件 {/*controlling-non-react-widgets*/}
<<<<<<< HEAD
有时你需要添加不是用 React 实现的 UI 小部件。比如说你想在你的页面添加一个地图组件。它有一个 `setZoomLevel()` 方法,然后你希望地图的缩放比例和代码中的 `zoomLevel` state 保持同步。你的 Effect 应该类似于:
=======
Sometimes you need to add UI widgets that aren't written in React. For example, let's say you're adding a map component to your page. It has a `setZoomLevel()` method, and you'd like to keep the zoom level in sync with a `zoomLevel` state variable in your React code. Your Effect would look similar to this:
>>>>>>> 589a1d3a8182d851718840f91bec80b0a13e2495
```js
useEffect(() => {
Expand Down
10 changes: 1 addition & 9 deletions src/content/learn/thinking-in-react.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,19 +270,11 @@ props 和 state 是不同的,但它们可以共同工作。父组件将经常

现在为这个 state 贯彻我们的策略:

<<<<<<< HEAD
1. **验证使用 state 的组件**
* `ProductTable` 需要基于 state (搜索文本和复选框值) 过滤产品列表。
* `SearchBar` 需要展示 state (搜索文本和复选框值)。
2. **寻找它们的父组件**:它们的第一个共同父组件为 `FilterableProductTable`
3. **决定 state 放置的地方**:我们将放置过滤文本和勾选 state 的值于 `FilterableProductTable`
=======
1. **Identify components that use state:**
* `ProductTable` needs to filter the product list based on that state (search text and checkbox value).
* `SearchBar` needs to display that state (search text and checkbox value).
2. **Find their common parent:** The first parent component both components share is `FilterableProductTable`.
3. **Decide where the state lives**: We'll keep the filter text and checked state values in `FilterableProductTable`.
>>>>>>> 589a1d3a8182d851718840f91bec80b0a13e2495
3. **决定 state 放置的地方**:我们将过滤文本和勾选 state 的值放置于 `FilterableProductTable` 中。

所以 state 将被放置在 `FilterableProductTable`

Expand Down
6 changes: 1 addition & 5 deletions src/content/learn/tutorial-tic-tac-toe.md
Original file line number Diff line number Diff line change
Expand Up @@ -1133,11 +1133,7 @@ export default function Board() {
<Note>
<<<<<<< HEAD
JavaScript 支持闭包,这意味着内部函数(例如 `handleClick`)可以访问外部函数(例如 `Board`)中定义的变量和函数。`handleClick` 函数可以读取 `squares` state 并调用 `setSquares` 方法,因为它们都是在 `Board` 函数内部定义的。
=======
JavaScript supports [closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures) which means an inner function (e.g. `handleClick`) has access to variables and functions defined in an outer function (e.g. `Board`). The `handleClick` function can read the `squares` state and call the `setSquares` method because they are both defined inside of the `Board` function.
>>>>>>> 589a1d3a8182d851718840f91bec80b0a13e2495
JavaScript 支持 [闭包](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures),这意味着内部函数(例如 `handleClick`)可以访问外部函数(例如 `Board`)中定义的变量和函数。`handleClick` 函数可以读取 `squares` state 并调用 `setSquares` 方法,因为它们都是在 `Board` 函数内部定义的。
</Note>
Expand Down
4 changes: 0 additions & 4 deletions src/content/learn/updating-objects-in-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -383,11 +383,7 @@ input { margin-left: 5px; margin-bottom: 5px; }

#### 使用一个事件处理函数来更新多个字段 {/*using-a-single-event-handler-for-multiple-fields*/}

<<<<<<< HEAD
你也可以在对象的定义中使用 `[``]` 括号来实现属性的动态命名。下面是同一个例子,但它使用了一个事件处理函数而不是三个:
=======
You can also use the `[` and `]` braces inside your object definition to specify a property with a dynamic name. Here is the same example, but with a single event handler instead of three different ones:
>>>>>>> 589a1d3a8182d851718840f91bec80b0a13e2495

<Sandpack>

Expand Down
9 changes: 0 additions & 9 deletions src/content/reference/react-dom/preinitModule.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,12 @@ function AppRoot() {

#### 参数 {/*parameters*/}

<<<<<<< HEAD
* `href`:字符串,要下载并执行的模块的 URL。
* `options`:对象,可以包含以下属性:
* `as`:必需的字符串,只能是 `script`
* `crossOrigin`:字符串,表示要使用的 [CORS 策略](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Attributes/crossorigin),可能的值为 `anonymous``use-credentials`
* `integrity`:字符串,为资源的加密哈希,用于 [验证其真实性](https://developer.mozilla.org/zh-CN/docs/Web/Security/Subresource_Integrity)
* `nonce`:字符串,表示使用严格内容安全策略时允许资源的 [加密随机数](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/nonce)
=======
* `href`: a string. The URL of the module you want to download and execute.
* `options`: an object. It contains the following properties:
* `as`: a required string. It must be `'script'`.
* `crossOrigin`: a string. The [CORS policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) to use. Its possible values are `anonymous` and `use-credentials`.
* `integrity`: a string. A cryptographic hash of the module, to [verify its authenticity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity).
* `nonce`: a string. A cryptographic [nonce to allow the module](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce) when using a strict Content Security Policy.
>>>>>>> 589a1d3a8182d851718840f91bec80b0a13e2495

#### 返回值 {/*returns*/}

Expand Down
15 changes: 0 additions & 15 deletions src/content/reference/react-dom/server/renderToPipeableStream.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ const { pipe } = renderToPipeableStream(<App />, {
* `reactNode`:想要将其渲染为 HTML 的 React 节点,比如像 `<App />` 这样的 JSX 元素。这样做意味着整个页面文档都将被渲染,所以这里提到的 `App` 组件将渲染 `<html>` 标签.
<<<<<<< HEAD
* **可选** `options`:用于配置流的对象.
* **可选** `bootstrapScriptContent`:指定一个字符串,这个字符串将被放入 `<script>` 标签中作为其内容。
* **可选** `bootstrapScripts`:一个 URL 字符串数组,它们将被转化为 `<script>` 标签嵌入页面。请将那些调用了 [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) 的 `<script>` 对应的 URL 放入这个数组中。但是如果你不想让客户都端运行 React 的话,请省略这个参数。
Expand All @@ -61,20 +60,6 @@ const { pipe } = renderToPipeableStream(<App />, {
* **可选** `onShellReady`:一个回调函数,在 [shell 初始化](#specifying-what-goes-into-the-shell) 渲染后立即调用。你可以 [设置状态码](#setting-the-status-code) 然后在这里调用 `pipe` 方法启用流式传输。这样一来,React 将会初始化 shell 渲染完毕后,通过上面提到的 `<script>` 进行 [流式传输更多内容](#streaming-more-content-as-it-loads),用这些内容替换掉 HTML 的加载中的后备方案。
* **可选** `onShellError`:一个回调函数,在初始化 shell 发生错误渲染时调用。它的第一个参数将自动接收捕获到的异常错误。此时,这个流中的任何内容都不会被发送,并且 `onShellReady``onAllReady` 都不会被调用,所以你还可以 [输出一段后备 HTML shell](#recovering-from-errors-inside-the-shell) 作为兜底。
* **可选** `progressiveChunkSize`:一个块中的字节数。[查阅更多关于该参数默认值的信息](https://github.com/facebook/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-server/src/ReactFizzServer.js#L210-L225)。
=======
* **optional** `options`: An object with streaming options.
* **optional** `bootstrapScriptContent`: If specified, this string will be placed in an inline `<script>` tag.
* **optional** `bootstrapScripts`: An array of string URLs for the `<script>` tags to emit on the page. Use this to include the `<script>` that calls [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot) Omit it if you don't want to run React on the client at all.
* **optional** `bootstrapModules`: Like `bootstrapScripts`, but emits [`<script type="module">`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) instead.
* **optional** `identifierPrefix`: A string prefix React uses for IDs generated by [`useId`.](/reference/react/useId) Useful to avoid conflicts when using multiple roots on the same page. Must be the same prefix as passed to [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot#parameters)
* **optional** `namespaceURI`: A string with the root [namespace URI](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS#important_namespace_uris) for the stream. Defaults to regular HTML. Pass `'http://www.w3.org/2000/svg'` for SVG or `'http://www.w3.org/1998/Math/MathML'` for MathML.
* **optional** `nonce`: A [`nonce`](http://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#nonce) string to allow scripts for [`script-src` Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src).
* **optional** `onAllReady`: A callback that fires when all rendering is complete, including both the [shell](#specifying-what-goes-into-the-shell) and all additional [content.](#streaming-more-content-as-it-loads) You can use this instead of `onShellReady` [for crawlers and static generation.](#waiting-for-all-content-to-load-for-crawlers-and-static-generation) If you start streaming here, you won't get any progressive loading. The stream will contain the final HTML.
* **optional** `onError`: A callback that fires whenever there is a server error, whether [recoverable](#recovering-from-errors-outside-the-shell) or [not.](#recovering-from-errors-inside-the-shell) By default, this only calls `console.error`. If you override it to [log crash reports,](#logging-crashes-on-the-server) make sure that you still call `console.error`. You can also use it to [adjust the status code](#setting-the-status-code) before the shell is emitted.
* **optional** `onShellReady`: A callback that fires right after the [initial shell](#specifying-what-goes-into-the-shell) has been rendered. You can [set the status code](#setting-the-status-code) and call `pipe` here to start streaming. React will [stream the additional content](#streaming-more-content-as-it-loads) after the shell along with the inline `<script>` tags that replace the HTML loading fallbacks with the content.
* **optional** `onShellError`: A callback that fires if there was an error rendering the initial shell. It receives the error as an argument. No bytes were emitted from the stream yet, and neither `onShellReady` nor `onAllReady` will get called, so you can [output a fallback HTML shell.](#recovering-from-errors-inside-the-shell)
* **optional** `progressiveChunkSize`: The number of bytes in a chunk. [Read more about the default heuristic.](https://github.com/facebook/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-server/src/ReactFizzServer.js#L210-L225)
>>>>>>> 589a1d3a8182d851718840f91bec80b0a13e2495
#### 返回值 {/*returns*/}
Expand Down
30 changes: 13 additions & 17 deletions src/content/reference/react/useMemo.md
Original file line number Diff line number Diff line change
Expand Up @@ -1056,12 +1056,9 @@ label {

---

<<<<<<< HEAD
### 记忆另一个 Hook 的依赖 {/*memoizing-a-dependency-of-another-hook*/}
=======
### Preventing an Effect from firing too often {/*preventing-an-effect-from-firing-too-often*/}
### 防止过于频繁地触发 Effect {/*preventing-an-effect-from-firing-too-often*/}

Sometimes, you might want to use a value inside an [Effect:](/learn/synchronizing-with-effects)
有时你可能会想要在 [Effect](/learn/synchronizing-with-effects) 中使用变量:

```js {4-7,10}
function ChatRoom({ roomId }) {
Expand All @@ -1078,19 +1075,19 @@ function ChatRoom({ roomId }) {
// ...
```
This creates a problem. [Every reactive value must be declared as a dependency of your Effect.](/learn/lifecycle-of-reactive-effects#react-verifies-that-you-specified-every-reactive-value-as-a-dependency) However, if you declare `options` as a dependency, it will cause your Effect to constantly reconnect to the chat room:
但是这样做会带来一些问题。因为 [Effect 中的每一个响应式值都应该声明为其依赖。](/learn/lifecycle-of-reactive-effects#react-verifies-that-you-specified-every-reactive-value-as-a-dependency) 然而如果你将 `options` 声明为依赖,会导致在 Effect 中不断地重新连接到聊天室:
```js {5}
useEffect(() => {
const connection = createConnection(options);
connection.connect();
return () => connection.disconnect();
}, [options]); // 🔴 Problem: This dependency changes on every render
}, [options]); // 🔴 问题:每次渲染这个依赖项都会发生改变
// ...
```
To solve this, you can wrap the object you need to call from an Effect in `useMemo`:
为了解决这个场景,你可以使用 `useMemo`Effect 中使用的对象包装起来:
```js {4-9,16}
function ChatRoom({ roomId }) {
Expand All @@ -1101,43 +1098,42 @@ function ChatRoom({ roomId }) {
serverUrl: 'https://localhost:1234',
roomId: roomId
};
}, [roomId]); //Only changes when roomId changes
}, [roomId]); //只有当 roomId 改变时才会被改变

useEffect(() => {
const options = createOptions();
const connection = createConnection(options);
connection.connect();
return () => connection.disconnect();
}, [options]); //Only changes when createOptions changes
}, [options]); //只有当 createOptions 改变时才会被改变
// ...
```
This ensures that the `options` object is the same between re-renders if `useMemo` returns the cached object.
因为 `useMemo` 返回了缓存的对象,所以这将确保 `options` 对象在重新渲染期间保持不变。
However, since `useMemo` is performance optimization, not a semantic guarantee, React may throw away the cached value if [there is a specific reason to do that](#caveats). This will also cause the effect to re-fire, **so it's even better to remove the need for a function dependency** by moving your object *inside* the Effect:
然而,因为 `useMemo` 只是一个性能优化手段,而并不是语义上的保证,所以 React 在 [特定场景下](#caveats) 会丢弃缓存值。这也会导致重新触发 Effect,因此 **最好通过将对象移动到 Effect 内部来消除对函数的依赖**:
```js {5-8,13}
function ChatRoom({ roomId }) {
const [message, setMessage] = useState('');

useEffect(() => {
const options = { //No need for useMemo or object dependencies!
const options = { //不需要将 useMemo 或对象作为依赖!
serverUrl: 'https://localhost:1234',
roomId: roomId
}

const connection = createConnection(options);
connection.connect();
return () => connection.disconnect();
}, [roomId]); //Only changes when roomId changes
}, [roomId]); //只有当 roomId 改变时才会被改变
// ...
```
Now your code is simpler and doesn't need `useMemo`. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect)
现在你的代码不需要使用 `useMemo` 并且更加简洁。[了解移除 Effect 依赖项的更多信息。](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect)
### Memoizing a dependency of another Hook {/*memoizing-a-dependency-of-another-hook*/}
>>>>>>> 589a1d3a8182d851718840f91bec80b0a13e2495
### 记忆另一个 Hook 的依赖 {/*memoizing-a-dependency-of-another-hook*/}
假设你有一个计算函数依赖于直接在组件主体中创建的对象:
Expand Down
7 changes: 1 addition & 6 deletions src/content/reference/react/useReducer.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,9 @@ function MyComponent() {
#### 注意事项 {/*caveats*/}
<<<<<<< HEAD
* `useReducer` 是一个 Hook,所以只能在 **组件的顶层作用域** 或自定义 Hook 中调用,而不能在循环或条件语句中调用。如果你有这种需求,可以创建一个新的组件,并把 state 移入其中。
* `dispatch` 函数具有稳定的标识,所以你经常会看到 Effect 的依赖数组中会省略它,即使包含它也不会导致 Effect 重新触发。如果 linter 允许你省略依赖项并且没有报错,那么你就可以安全地省略它。[了解移除 Effect 依赖项的更多信息。](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect)
* 严格模式下 React 会 **调用两次 reducer 和初始化函数**,这可以 [帮助你发现意外的副作用](#my-reducer-or-initializer-function-runs-twice)。这只是开发模式下的行为,并不会影响生产环境。只要 reducer 和初始化函数是纯函数(理应如此)就不会改变你的逻辑。其中一个调用结果会被忽略。
=======
* `useReducer` is a Hook, so you can only call it **at the top level of your component** or your own Hooks. You can't call it inside loops or conditions. If you need that, extract a new component and move the state into it.
* The `dispatch` function has a stable identity, so you will often see it omitted from effect dependencies, but including it will not cause the effect to fire. If the linter lets you omit a dependency without errors, it is safe to do. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect)
* In Strict Mode, React will **call your reducer and initializer twice** in order to [help you find accidental impurities.](#my-reducer-or-initializer-function-runs-twice) This is development-only behavior and does not affect production. If your reducer and initializer are pure (as they should be), this should not affect your logic. The result from one of the calls is ignored.
>>>>>>> 589a1d3a8182d851718840f91bec80b0a13e2495
---
Expand Down
Loading

0 comments on commit 27ca116

Please sign in to comment.