Skip to content
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

docs(cn): translate reference/react/useImperativeHandle into Chinese #1123

Merged
merged 5 commits into from
Apr 9, 2023
Merged
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
48 changes: 24 additions & 24 deletions src/content/reference/react/useImperativeHandle.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: useImperativeHandle

<Intro>

`useImperativeHandle` is a React Hook that lets you customize the handle exposed as a [ref.](/learn/manipulating-the-dom-with-refs)
`useImperativeHandle` React 中的一个 Hook,它能让你自定义由 [ref](/learn/manipulating-the-dom-with-refs) 暴露出来的句柄。

```js
useImperativeHandle(ref, createHandle, dependencies?)
Expand All @@ -16,45 +16,45 @@ useImperativeHandle(ref, createHandle, dependencies?)

---

## Reference {/*reference*/}
## 参考 {/*reference*/}

### `useImperativeHandle(ref, createHandle, dependencies?)` {/*useimperativehandle*/}

Call `useImperativeHandle` at the top level of your component to customize the ref handle it exposes:
在组件顶层通过调用 `useImperativeHandle` 来自定义 ref 暴露出来的句柄:

```js
import { forwardRef, useImperativeHandle } from 'react';

const MyInput = forwardRef(function MyInput(props, ref) {
useImperativeHandle(ref, () => {
return {
// ... your methods ...
// ... 你的方法 ...
};
}, []);
// ...
```

[See more examples below.](#usage)
[请看下面的更多例子](#usage)

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

* `ref`: The `ref` you received as the second argument from the [`forwardRef` render function.](/reference/react/forwardRef#render-function)
* `ref`:该 `ref` 是你从 [`forwardRef` 渲染函数](/reference/react/forwardRef#render-function) 中获得的第二个参数。

* `createHandle`: A function that takes no arguments and returns the ref handle you want to expose. That ref handle can have any type. Usually, you will return an object with the methods you want to expose.
* `createHandle`:该函数无需参数,它返回你想要暴露的 ref 的句柄。该句柄可以包含任何类型。通常,你会返回一个包含你想暴露的方法的对象。

* **optional** `dependencies`: The list of all reactive values referenced inside of the `createHandle` code. Reactive values include props, state, and all the variables and functions declared directly inside your component body. If your linter is [configured for React](/learn/editor-setup#linting), it will verify that every reactive value is correctly specified as a dependency. The list of dependencies must have a constant number of items and be written inline like `[dep1, dep2, dep3]`. React will compare each dependency with its previous value using the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. If a re-render resulted in a change to some dependency, or if you omitted this argument, your `createHandle` function will re-execute, and the newly created handle will be assigned to the ref.
* **可选的** `dependencies`:函数 `createHandle` 代码中所用到的所有反应式的值的列表。反应式的值包含 props、状态和其他所有直接在你组件体内声明的变量和函数。倘若你的代码检查器已 [为 React 配置好](/learn/editor-setup#linting),它会验证每一个反应式的值是否被正确指定为依赖项。该列表的长度必须是一个常数项,并且必须按照 `[dep1, dep2, dep3]` 的形式罗列各依赖项。React 会使用 [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) 来比较每一个依赖项与其对应的之前值。如果一次重新渲染导致某些依赖项发生了改变,或你没有提供这个参数列表,你的函数 `createHandle` 将会被重新执行,而新生成的句柄则会被分配给 ref

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

`useImperativeHandle` returns `undefined`.
`useImperativeHandle` 返回 `undefined`

---

## Usage {/*usage*/}
## 使用方法 {/*usage*/}

### Exposing a custom ref handle to the parent component {/*exposing-a-custom-ref-handle-to-the-parent-component*/}
### 向父组件暴露一个自定义的 ref 句柄 {/*exposing-a-custom-ref-handle-to-the-parent-component*/}

By default, components don't expose their DOM nodes to parent components. For example, if you want the parent component of `MyInput` to [have access](/learn/manipulating-the-dom-with-refs) to the `<input>` DOM node, you have to opt in with [`forwardRef`:](/reference/react/forwardRef)
默认情况下,组件不会将它们的 DOM 节点暴露给父组件。举例来说,如果你想要 `MyInput` 的父组件 [能访问到](/learn/manipulating-the-dom-with-refs) `<input>` DOM 节点,你必须选择使用 [`forwardRef`:](/reference/react/forwardRef)

```js {4}
import { forwardRef } from 'react';
Expand All @@ -64,25 +64,25 @@ const MyInput = forwardRef(function MyInput(props, ref) {
});
```

With the code above, [a ref to `MyInput` will receive the `<input>` DOM node.](/reference/react/forwardRef#exposing-a-dom-node-to-the-parent-component) However, you can expose a custom value instead. To customize the exposed handle, call `useImperativeHandle` at the top level of your component:
在上方的代码中,[`MyInput` 的 ref 会接收到 `<input>` DOM 节点](/reference/react/forwardRef#exposing-a-dom-node-to-the-parent-component)。然而,你可以选择暴露一个自定义的值。为了修改被暴露的句柄,在你的顶层组件调用 `useImperativeHandle`

```js {4-8}
import { forwardRef, useImperativeHandle } from 'react';

const MyInput = forwardRef(function MyInput(props, ref) {
useImperativeHandle(ref, () => {
return {
// ... your methods ...
// ... 你的方法 ...
};
}, []);

return <input {...props} />;
});
```

Note that in the code above, the `ref` is no longer forwarded to the `<input>`.
注意在上述代码中,该 `ref` 已不再被转发到 `<input>` 中。

For example, suppose you don't want to expose the entire `<input>` DOM node, but you want to expose two of its methods: `focus` and `scrollIntoView`. To do this, keep the real browser DOM in a separate ref. Then use `useImperativeHandle` to expose a handle with only the methods that you want the parent component to call:
举例来说,假设你不想暴露出整个 `<input>` DOM 节点,但你想要它其中两个方法:`focus` `scrollIntoView`。为此,用单独额外的 ref 来指向真实的浏览器 DOM。然后使用 `useImperativeHandle` 来暴露一个句柄,它只返回你想要父组件去调用的方法:

```js {7-14}
import { forwardRef, useRef, useImperativeHandle } from 'react';
Expand All @@ -105,7 +105,7 @@ const MyInput = forwardRef(function MyInput(props, ref) {
});
```

Now, if the parent component gets a ref to `MyInput`, it will be able to call the `focus` and `scrollIntoView` methods on it. However, it will not have full access to the underlying `<input>` DOM node.
现在,如果你的父组件获得了 `MyInput` 的 ref,就能通过该 ref 来调用 `focus` `scrollIntoView` 方法。然而,它的访问是受限的,无法读取或调用下方 `<input>` DOM 节点的其他所有属性和方法。

<Sandpack>

Expand All @@ -118,7 +118,7 @@ export default function Form() {

function handleClick() {
ref.current.focus();
// This won't work because the DOM node isn't exposed:
// 下方代码不起作用,因为 DOM 节点并未被暴露出来:
// ref.current.style.opacity = 0.5;
}

Expand Down Expand Up @@ -166,9 +166,9 @@ input {

---

### Exposing your own imperative methods {/*exposing-your-own-imperative-methods*/}
### 暴露你自己的命令式方法 {/*exposing-your-own-imperative-methods*/}

The methods you expose via an imperative handle don't have to match the DOM methods exactly. For example, this `Post` component exposes a `scrollAndFocusAddComment` method via an imperative handle. This lets the parent `Page` scroll the list of comments *and* focus the input field when you click the button:
你通过命令式句柄暴露出来的方法不一定需要完全匹配 DOM 节点的方法。例如,这个 `Post` 组件暴露了一个 `scrollAndFocusAddComment` 方法。它可以让你在点击按钮后,使父组件 `Page` 滚动到评论列表的底部 *并* 聚焦到输入框:

<Sandpack>

Expand Down Expand Up @@ -281,8 +281,8 @@ export default AddComment;

<Pitfall>

**Do not overuse refs.** You should only use refs for *imperative* behaviors that you can't express as props: for example, scrolling to a node, focusing a node, triggering an animation, selecting text, and so on.
**不要滥用 ref。** 你应当仅在你没法通过 prop 来表达 *命令式* 行为的时候才使用 ref:例如,滚动到指定节点、聚焦某个节点、触发一次动画,以及选择文本等等。

**If you can express something as a prop, you should not use a ref.** For example, instead of exposing an imperative handle like `{ open, close }` from a `Modal` component, it is better to take `isOpen` as a prop like `<Modal isOpen={isOpen} />`. [Effects](/learn/synchronizing-with-effects) can help you expose imperative behaviors via props.
**如果可以通过 prop 实现,那就不应该使用 ref**。例如,你不应该从一个 `Model` 组件暴露出 `{open, close}` 这样的命令式句柄,最好是像 `<Modal isOpen={isOpen} />` 这样,将 `isOpen` 作为一个 prop。[副作用](/learn/synchronizing-with-effects) 可以帮你通过 prop 来暴露一些命令式的行为。

</Pitfall>