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-dom/findDOMNode into Chinese #1203

Merged
merged 6 commits into from
Jun 25, 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
104 changes: 52 additions & 52 deletions src/content/reference/react-dom/findDOMNode.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ title: findDOMNode

<Deprecated>

This API will be removed in a future major version of React. [See the alternatives.](#alternatives)
API 将在未来的 React 主要版本中被移除。[请查看替代方案](#alternatives)

</Deprecated>

<Intro>

`findDOMNode` finds the browser DOM node for a React [class component](/reference/react/Component) instance.
`findDOMNode` 方法可以获取 [类式组件](/reference/react/Component) 实例对应的浏览器 DOM 节点。

```js
const domNode = findDOMNode(componentInstance)
Expand All @@ -22,46 +22,46 @@ const domNode = findDOMNode(componentInstance)

---

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

### `findDOMNode(componentInstance)` {/*finddomnode*/}

Call `findDOMNode` to find the browser DOM node for a given React [class component](/reference/react/Component) instance.
使用 `findDOMNode` 获取 [类式组件](/reference/react/Component) 实例对应的浏览器 DOM 节点。

```js
import { findDOMNode } from 'react-dom';

const domNode = findDOMNode(componentInstance);
```

[See more examples below.](#usage)
[参见下面更多示例](#usage)

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

* `componentInstance`: An instance of the [`Component`](/reference/react/Component) subclass. For example, `this` inside a class component.
* `componentInstance`[`Component`](/reference/react/Component) 子类的实例。举个例子,类式组件中的 `this`


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

`findDOMNode` returns the first closest browser DOM node within the given `componentInstance`. When a component renders to `null`, or renders `false`, `findDOMNode` returns `null`. When a component renders to a string, `findDOMNode` returns a text DOM node containing that value.
`findDOMNode` 方法返回与给定的 `componentInstance` 中最接近的浏览器 DOM 节点。当组件渲染为 `null``false` 时,`findDOMNode` 返回 `null`。当组件渲染为字符串时,`findDOMNode` 返回一个包含该值的文本 DOM 节点。

#### Caveats {/*caveats*/}
#### 注意 {/*caveats*/}

* A component may return an array or a [Fragment](/reference/react/Fragment) with multiple children. In that case `findDOMNode`, will return the DOM node corresponding to the first non-empty child.
* 组件可能会返回包含多个子元素的数组或 [Fragment](/reference/react/Fragment)。在这种情况下,`findDOMNode` 会返回第一个非空子节点对应的 DOM 节点。

* `findDOMNode` only works on mounted components (that is, components that have been placed in the DOM). If you try to call this on a component that has not been mounted yet (like calling `findDOMNode()` in `render()` on a component that has yet to be created), an exception will be thrown.
* `findDOMNode` 只对已经挂载到 DOM 上的组件有效。如果你尝试在一个还未挂载的组件上调用 `findDOMNode()`(比如在一个还未创建的组件的 `render()` 方法中调用 `findDOMNode()`),会抛出异常。

* `findDOMNode` only returns the result at the time of your call. If a child component renders a different node later, there is no way for you to be notified of this change.
* `findDOMNode` 只会返回调用时的结果,你无法得知组件是否在之后渲染了不同的节点。

* `findDOMNode` accepts a class component instance, so it can't be used with function components.
* `findDOMNode` 接受类组件实例作为参数,而不能用于函数式组件。

---

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

### Finding the root DOM node of a class component {/*finding-the-root-dom-node-of-a-class-component*/}
### 寻找类式组件对应的 DOM 节点 {/*finding-the-root-dom-node-of-a-class-component*/}

Call `findDOMNode` with a [class component](/reference/react/Component) instance (usually, `this`) to find the DOM node it has rendered.
使用 `findDOMNode` 获取 [类式组件](/reference/react/Component) 实例(通常是 `this`)对应的已渲染 DOM 节点。

```js {3}
class AutoselectingInput extends Component {
Expand All @@ -71,12 +71,12 @@ class AutoselectingInput extends Component {
}

render() {
return <input defaultValue="Hello" />
return <input defaultValue="你好" />
}
}
```

Here, the `input` variable will be set to the `<input>` DOM element. This lets you do something with it. For example, when clicking "Show example" below mounts the input, [`input.select()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select) selects all text in the input:
在这里,`input` 变量将被设置为 `<input>` DOM 元素,这样你就可以对其进行操作。例如,当点击下方的“显示示例”按钮并挂载了输入框后,[`input.select()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select) 会选中输入框中的所有文本:

<Sandpack>

Expand All @@ -89,7 +89,7 @@ export default function App() {
return (
<>
<button onClick={() => setShow(true)}>
Show example
显示示例
</button>
<hr />
{show && <AutoselectingInput />}
Expand All @@ -109,7 +109,7 @@ class AutoselectingInput extends Component {
}

render() {
return <input defaultValue="Hello" />
return <input defaultValue="你好" />
}
}

Expand All @@ -120,11 +120,11 @@ export default AutoselectingInput;

---

## Alternatives {/*alternatives*/}
## 替代方案 {/*alternatives*/}

### Reading component's own DOM node from a ref {/*reading-components-own-dom-node-from-a-ref*/}
### 使用 ref 读取组件自己的 DOM 节点 {/*reading-components-own-dom-node-from-a-ref*/}

Code using `findDOMNode` is fragile because the connection between the JSX node and the code manipulating the corresponding DOM node is not explicit. For example, try wrapping this `<input />` into a `<div>`:
由于 JSX 节点与操作相应的 DOM 节点的代码之间的联系不是显式的,因此使用 `findDOMNode` 的代码非常脆弱。例如,尝试将此 `<input />` 包装在一个 `<div>` 中:

<Sandpack>

Expand All @@ -137,7 +137,7 @@ export default function App() {
return (
<>
<button onClick={() => setShow(true)}>
Show example
显示示例
</button>
<hr />
{show && <AutoselectingInput />}
Expand Down Expand Up @@ -165,9 +165,9 @@ export default AutoselectingInput;

</Sandpack>

This will break the code because now, `findDOMNode(this)` finds the `<div>` DOM node, but the code expects an `<input>` DOM node. To avoid these kinds of problems, use [`createRef`](/reference/react/createRef) to manage a specific DOM node.
这将出现问题。`findDOMNode(this)` 找到的是 `<div>` 节点,但其实我们期望找到的是 `<input>` 节点。为了避免这些问题,考虑使用 [`createRef`](/reference/react/createRef) 管理特定的 DOM 节点。

In this example, `findDOMNode` is no longer used. Instead, `inputRef = createRef(null)` is defined as an instance field on the class. To read the DOM node from it, you can use `this.inputRef.current`. To attach it to the JSX, you render `<input ref={this.inputRef} />`. This connects the code using the DOM node to its JSX:
在这个例子中不再使用 `findDOMNode`。相反,使用 `inputRef = createRef(null)` 并将其定义为类的实例字段。如果想要从中读取 DOM 节点,可以使用`this.inputRef.current`。如果想要将其附加在 JSX 上,考虑渲染 `<input ref={this.inputRef} />`。这将连接使用 DOM 节点的代码与对应 JSX

<Sandpack>

Expand All @@ -180,7 +180,7 @@ export default function App() {
return (
<>
<button onClick={() => setShow(true)}>
Show example
显示示例
</button>
<hr />
{show && <AutoselectingInput />}
Expand All @@ -202,7 +202,7 @@ class AutoselectingInput extends Component {

render() {
return (
<input ref={this.inputRef} defaultValue="Hello" />
<input ref={this.inputRef} defaultValue="你好" />
);
}
}
Expand All @@ -212,7 +212,7 @@ export default AutoselectingInput;

</Sandpack>

In modern React without class components, the equivalent code would call [`useRef`](/reference/react/useRef) instead:
在函数式组件中,你应该使用 [`useRef`](/reference/react/useRef)

<Sandpack>

Expand All @@ -225,7 +225,7 @@ export default function App() {
return (
<>
<button onClick={() => setShow(true)}>
Show example
显示示例
</button>
<hr />
{show && <AutoselectingInput />}
Expand All @@ -245,19 +245,19 @@ export default function AutoselectingInput() {
input.select();
}, []);

return <input ref={inputRef} defaultValue="Hello" />
return <input ref={inputRef} defaultValue="你好" />
}
```

</Sandpack>

[Read more about manipulating the DOM with refs.](/learn/manipulating-the-dom-with-refs)
如果你想了解更多,请阅读 [使用 ref 操作 DOM](/learn/manipulating-the-dom-with-refs)

---

### Reading a child component's DOM node from a forwarded ref {/*reading-a-child-components-dom-node-from-a-forwarded-ref*/}
### 使用 ref 操作子组件的 DOM 节点 {/*reading-a-child-components-dom-node-from-a-forwarded-ref*/}

In this example, `findDOMNode(this)` finds a DOM node that belongs to another component. The `AutoselectingInput` renders `MyInput`, which is your own component that renders a browser `<input>`.
在这个例子中,`findDOMNode(this)` 获取了属于另一个组件的 DOM 节点。`AutoselectingInput` 渲染了我们自己的 `MyInput` 组件,而 `MyInput` 渲染了浏览器标签 `<input>`

<Sandpack>

Expand All @@ -270,7 +270,7 @@ export default function App() {
return (
<>
<button onClick={() => setShow(true)}>
Show example
显示示例
</button>
<hr />
{show && <AutoselectingInput />}
Expand Down Expand Up @@ -299,20 +299,20 @@ export default AutoselectingInput;

```js MyInput.js
export default function MyInput() {
return <input defaultValue="Hello" />;
return <input defaultValue="你好" />;
}
```

</Sandpack>

Notice that calling `findDOMNode(this)` inside `AutoselectingInput` still gives you the DOM `<input>`--even though the JSX for this `<input>` is hidden inside the `MyInput` component. This seems convenient for the above example, but it leads to fragile code. Imagine that you wanted to edit `MyInput` later and add a wrapper `<div>` around it. This would break the code of `AutoselectingInput` (which expects to find an `<input>`).
请注意,即使 `<input>` 被隐藏在 `MyInput` 组件中,在 `AutoselectingInput` 中调用 `findDOMNode(this)` 仍然会返回 `<input>`。这在上面的例子中似乎很方便,但它会导致代码变得非常脆弱。想象一下,如果你以后想编辑 `MyInput` 并使用 `<div>` 包装,但是这将会破坏 `AutoselectingInput` 的代码(因为它期望找到 `<input>`)。
Yucohny marked this conversation as resolved.
Show resolved Hide resolved

To replace `findDOMNode` in this example, the two components need to coordinate:
考虑在这个例子中替换 `findDOMNode`,并且下列两个组件需要协同工作:

1. `AutoSelectingInput` should declare a ref, like [in the earlier example](#reading-components-own-dom-node-from-a-ref), and pass it to `<MyInput>`.
2. `MyInput` should be declared with [`forwardRef`](/reference/react/forwardRef) to take that ref and forward it down to the `<input>` node.
1. `AutoSelectingInput` 中声明一个 ref,就像 [前面的例子](#reading-components-own-dom-node-from-a-ref) 中一样,并将其传递给 `<MyInput>`
2. `MyInput` 使用 [`forwardRef`](/reference/react/forwardRef) 接收该 ref 并将其转发到 `<input>` 节点。

This version does that, so it no longer needs `findDOMNode`:
这种方式解决了这个问题,所以不再需要 `findDOMNode`

<Sandpack>

Expand All @@ -325,7 +325,7 @@ export default function App() {
return (
<>
<button onClick={() => setShow(true)}>
Show example
显示示例
</button>
<hr />
{show && <AutoselectingInput />}
Expand Down Expand Up @@ -360,15 +360,15 @@ export default AutoselectingInput;
import { forwardRef } from 'react';

const MyInput = forwardRef(function MyInput(props, ref) {
return <input ref={ref} defaultValue="Hello" />;
return <input ref={ref} defaultValue="你好" />;
});

export default MyInput;
```

</Sandpack>

Here is how this code would look like with function components instead of classes:
以下是上面代码在函数式组件中的样子:

<Sandpack>

Expand All @@ -381,7 +381,7 @@ export default function App() {
return (
<>
<button onClick={() => setShow(true)}>
Show example
显示示例
</button>
<hr />
{show && <AutoselectingInput />}
Expand All @@ -402,15 +402,15 @@ export default function AutoselectingInput() {
input.select();
}, []);

return <MyInput ref={inputRef} defaultValue="Hello" />
return <MyInput ref={inputRef} defaultValue="你好" />
}
```

```js MyInput.js
import { forwardRef } from 'react';

const MyInput = forwardRef(function MyInput(props, ref) {
return <input ref={ref} defaultValue="Hello" />;
return <input ref={ref} defaultValue="你好" />;
});

export default MyInput;
Expand All @@ -420,16 +420,16 @@ export default MyInput;

---

### Adding a wrapper `<div>` element {/*adding-a-wrapper-div-element*/}
### 使用 `<div>` 包装 {/*adding-a-wrapper-div-element*/}

Sometimes a component needs to know the position and size of its children. This makes it tempting to find the children with `findDOMNode(this)`, and then use DOM methods like [`getBoundingClientRect`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect) for measurements.
有时,一个组件想要知道子元素的位置和大小。这会让你想要使用 `findDOMNode(this)` 查找子元素,然后使用 [`getBoundingClientRect`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect) 等 DOM 方法来进行测量。

There is currently no direct equivalent for this use case, which is why `findDOMNode` is deprecated but is not yet removed completely from React. In the meantime, you can try rendering a wrapper `<div>` node around the content as a workaround, and getting a ref to that node. However, extra wrappers can break styling.
目前,还没有直接适用于此场景的替代方法,这就是为什么 `findDOMNode` 已弃用但尚未从 React 中完全删除的原因。在此期间,你可以尝试在内容周围使用 `<div>` 包装,并向其添加 ref。但是,额外的包装可能会破坏样式。

```js
<div ref={someRef}>
{children}
</div>
```

This also applies to focusing and scrolling to arbitrary children.
这对于聚焦以及滚动到任何子元素也是一样。