You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/docs/refs-and-the-dom.md
+62-61Lines changed: 62 additions & 61 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,33 +11,34 @@ redirect_from:
11
11
permalink: docs/refs-and-the-dom.html
12
12
---
13
13
14
-
Refs provide a way to access DOM nodes or React elements created in the render method.
14
+
Refs 提供了一种方式,允许我们访问 DOM 节点或在 render 方法中创建的 React 元素。
15
15
16
-
In the typical React dataflow, [props](/docs/components-and-props.html) are the only way that parent components interact with their children. To modify a child, you re-render it with new props. However, there are a few cases where you need to imperatively modify a child outside of the typical dataflow. The child to be modified could be an instance of a React component, or it could be a DOM element. For both of these cases, React provides an escape hatch.
Your first inclination may be to use refs to "make things happen" in your app. If this is the case, take a moment and think more critically about where state should be owned in the component hierarchy. Often, it becomes clear that the proper place to "own" that state is at a higher level in the hierarchy. See the [Lifting State Up](/docs/lifting-state-up.html)guide for examples of this.
33
+
你可能首先会想到使用 refs 在你的 app 中“让事情发生”。如果是这种情况,请花一点时间,认真再考虑一下 state 属性应该被安排在哪个组件层中。通常你会想明白,让更高的组件层级拥有这个 state,是更恰当的。查看 [Lifting State Up](/docs/lifting-state-up.html)以获取更多有关示例。
33
34
34
-
> Note
35
+
> 注意:
35
36
>
36
-
> The examples below have been updated to use the `React.createRef()` API introduced in React 16.3. If you are using an earlier release of React, we recommend using [callback refs](#callback-refs) instead.
Refs are created using `React.createRef()`and attached to React elements via the `ref`attribute. Refs are commonly assigned to an instance property when a component is constructed so they can be referenced throughout the component.
The value of the ref differs depending on the type of the node:
63
+
ref 的值根据节点的类型而有所不同:
63
64
64
-
-When the `ref`attribute is used on an HTML element, the `ref` created in the constructor with `React.createRef()`receives the underlying DOM element as its `current`property.
65
-
-When the `ref`attribute is used on a custom class component, the `ref`object receives the mounted instance of the component as its `current`.
66
-
-**You may not use the `ref`attribute on function components** because they don't have instances.
65
+
-当 `ref`属性用于 HTML 元素时,构造函数中使用 `React.createRef()`创建的 `ref` 接收底层 DOM 元素作为其 `current`属性。
66
+
-当 `ref`属性用于自定义 class 组件时,`ref`对象接收组件的挂载实例作为其 `current` 属性。
67
+
-**你不能在函数式组件上使用 `ref`属性**,因为他们没有实例。
67
68
68
-
The examples below demonstrate the differences.
69
+
以下例子说明了这些差异。
69
70
70
-
#### Adding a Ref to a DOM Element {#adding-a-ref-to-a-dom-element}
71
+
#### 为 DOM 元素添加 ref {#adding-a-ref-to-a-dom-element}
71
72
72
-
This code uses a `ref`to store a reference to a DOM node:
73
+
以下代码使用 `ref`去存储 DOM 节点的引用:
73
74
74
75
```javascript{5,12,22}
75
76
class CustomTextInput extends React.Component {
76
77
constructor(props) {
77
78
super(props);
78
-
// create a ref to store the textInput DOM element
// Explicitly focus the text input using the raw DOM API
85
-
// Note: we're accessing "current" to get the DOM node
85
+
// 直接使用原生 API 使 text 输入框获得焦点
86
+
// 注意:我们通过 "current" 来访问 DOM 节点
86
87
this.textInput.current.focus();
87
88
}
88
89
89
90
render() {
90
-
// tell React that we want to associate the <input> ref
91
-
// with the `textInput` that we created in the constructor
91
+
// 告诉 React 我们想把 <input> ref 关联到
92
+
// 构造器里创建的 `textInput` 上
92
93
return (
93
94
<div>
94
95
<input
@@ -105,11 +106,11 @@ class CustomTextInput extends React.Component {
105
106
}
106
107
```
107
108
108
-
React will assign the `current`property with the DOM element when the component mounts, and assign it back to `null`when it unmounts. `ref`updates happen before `componentDidMount`or`componentDidUpdate`lifecycle methods.
109
+
React 会在组件挂载时给 `current`属性传入 DOM 元素,并在组件卸载时传入 `null`值。`ref`会在 `componentDidMount`或`componentDidUpdate`生命周期钩子触发前更新。
109
110
110
-
#### Adding a Ref to a Class Component {#adding-a-ref-to-a-class-component}
111
+
#### 为 class 组件添加 Ref {#adding-a-ref-to-a-class-component}
111
112
112
-
If we wanted to wrap the `CustomTextInput` above to simulate it being clicked immediately after mounting, we could use a ref to get access to the custom input and call its `focusTextInput`method manually:
class AutoFocusTextInput extends React.Component {
@@ -130,17 +131,17 @@ class AutoFocusTextInput extends React.Component {
130
131
}
131
132
```
132
133
133
-
Note that this only works if `CustomTextInput`is declared as a class:
134
+
请注意,这仅在 `CustomTextInput`声明为类时才有效:
134
135
135
136
```js{1}
136
137
class CustomTextInput extends React.Component {
137
138
// ...
138
139
}
139
140
```
140
141
141
-
#### Refs and Function Components {#refs-and-function-components}
142
+
#### Refs 与函数式组件 {#refs-and-function-components}
142
143
143
-
**You may not use the `ref` attribute on function components** because they don't have instances:
144
+
**你不能在函数式组件上使用 ref 属性**,因为它们没有实例:
144
145
145
146
```javascript{1,8,13}
146
147
function MyFunctionComponent() {
@@ -161,13 +162,13 @@ class Parent extends React.Component {
161
162
}
162
163
```
163
164
164
-
You should convert the component to a class if you need a ref to it, just like you do when you need lifecycle methods or state.
165
+
如果你需要使用 ref,你应该将组件转化为一个 class,就像当你需要使用生命周期钩子或 state 时一样。
165
166
166
-
You can, however, **use the `ref`attribute inside a function component** as long as you refer to a DOM element or a class component:
167
+
不管怎样,你可以**在函数式组件内部使用 `ref`属性**,只要它指向一个 DOM 元素或 class 组件:
167
168
168
169
```javascript{2,3,6,13}
169
170
function CustomTextInput(props) {
170
-
// textInput must be declared here so the ref can refer to it
171
+
// 这里必须声明 textInput,这样 ref 才可以引用它
171
172
let textInput = React.createRef();
172
173
173
174
function handleClick() {
@@ -189,25 +190,25 @@ function CustomTextInput(props) {
189
190
}
190
191
```
191
192
192
-
### Exposing DOM Refs to Parent Components {#exposing-dom-refs-to-parent-components}
193
+
### 将 DOM Refs 暴露给父组件 {#exposing-dom-refs-to-parent-components}
193
194
194
-
In rare cases, you might want to have access to a child's DOM node from a parent component. This is generally not recommended because it breaks component encapsulation, but it can occasionally be useful for triggering focus or measuring the size or position of a child DOM node.
195
+
在极少数情况下,你可能希望在父组件中引用子节点的 DOM 节点。通常不建议这样做,因为它会打破组件的封装,但它偶尔可用于触发焦点或测量子 DOM 节点的大小或位置。
195
196
196
-
While you could [add a ref to the child component](#adding-a-ref-to-a-class-component), this is not an ideal solution, as you would only get a component instance rather than a DOM node. Additionally, this wouldn't work with function components.
197
+
虽然你可以[向子组件添加 ref](#adding-a-ref-to-a-class-component),但这不是一个理想的解决方案,因为你只能获取组件实例而不是 DOM 节点。并且,它还在函数式组件上无效。
197
198
198
-
If you use React 16.3 or higher, we recommend to use [ref forwarding](/docs/forwarding-refs.html) for these cases. **Ref forwarding lets components opt into exposing any child component's ref as their own**. You can find a detailed example of how to expose a child's DOM node to a parent component [in the ref forwarding documentation](/docs/forwarding-refs.html#forwarding-refs-to-dom-components).
If you use React 16.2 or lower, or if you need more flexibility than provided by ref forwarding, you can use [this alternative approach](https://gist.github.com/gaearon/1a018a023347fe1c2476073330cc5509) and explicitly pass a ref as a differently named prop.
When possible, we advise against exposing DOM nodes, but it can be a useful escape hatch. Note that this approach requires you to add some code to the child component. If you have absolutely no control over the child component implementation, your last option is to use [`findDOMNode()`](/docs/react-dom.html#finddomnode), but it is discouraged and deprecated in [`StrictMode`](/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage).
203
+
可能的话,我们不建议暴露 DOM 节点,但有时候它会成为救命稻草。注意这个方案需要你在子组件中增加一些代码。如果你对子组件的实现没有控制权的话,你剩下的选择是使用 [`findDOMNode()`](/docs/react-dom.html#finddomnode),但这是不推荐的,而且在[`严格模式`](/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage) 下被禁用。
203
204
204
-
### Callback Refs {#callback-refs}
205
+
### 回调 Refs {#callback-refs}
205
206
206
-
React also supports another way to set refs called "callback refs", which gives more fine-grain control over when refs are set and unset.
Instead of passing a `ref` attribute created by `createRef()`, you pass a function. The function receives the React component instance or HTML DOM element as its argument, which can be stored and accessed elsewhere.
209
+
不同于传递 `createRef()` 创建的 `ref` 属性,你会传递一个函数。这个函数中接受 React 组件实例或 HTML DOM 元素作为参数,以存储它们并使它们能被其他地方访问。
209
210
210
-
The example below implements a common pattern: using the `ref`callback to store a reference to a DOM node in an instance property.
211
+
下面的例子描述了一个通用的范例:使用 `ref`回调函数,在实例的属性中存储对 DOM 节点的引用。
211
212
212
213
```javascript{5,7-9,11-14,19,29,34}
213
214
class CustomTextInput extends React.Component {
@@ -221,19 +222,19 @@ class CustomTextInput extends React.Component {
221
222
};
222
223
223
224
this.focusTextInput = () => {
224
-
// Focus the text input using the raw DOM API
225
+
// 使用原生 DOM API 使 text 输入框获得焦点
225
226
if (this.textInput) this.textInput.focus();
226
227
};
227
228
}
228
229
229
230
componentDidMount() {
230
-
// autofocus the input on mount
231
+
// 组件挂载后,让文本框自动获得焦点
231
232
this.focusTextInput();
232
233
}
233
234
234
235
render() {
235
-
// Use the `ref` callback to store a reference to the text input DOM
236
-
// element in an instance field (for example, this.textInput).
236
+
// 使用 `ref` 的回调函数将 text 输入框 DOM 节点的引用存储到 React
237
+
// 实例上(比如 this.textInput)
237
238
return (
238
239
<div>
239
240
<input
@@ -251,9 +252,9 @@ class CustomTextInput extends React.Component {
251
252
}
252
253
```
253
254
254
-
React will call the `ref`callback with the DOM element when the component mounts, and call it with `null` when it unmounts. Refs are guaranteed to be up-to-date before `componentDidMount`or`componentDidUpdate`fires.
255
+
React 将在组件挂载时,会调用 `ref`回调函数并传入 DOM 元素,当卸载时调用它并传入 null。在 `componentDidMount`或`componentDidUpdate`触发前,React 会保证refs 一定是最新的。
255
256
256
-
You can pass callback refs between components like you can with object refs that were created with `React.createRef()`.
@@ -275,16 +276,16 @@ class Parent extends React.Component {
275
276
}
276
277
```
277
278
278
-
In the example above, `Parent`passes its ref callback as an `inputRef`prop to the `CustomTextInput`, and the `CustomTextInput`passes the same function as a special `ref`attribute to the `<input>`. As a result, `this.inputElement`in `Parent` will be set to the DOM node corresponding to the `<input>` element in the `CustomTextInput`.
If you worked with React before, you might be familiar with an older API where the `ref` attribute is a string, like `"textInput"`, and the DOM node is accessed as `this.refs.textInput`. We advise against it because string refs have [some issues](https://github.com/facebook/react/pull/8333#issuecomment-271648615), are considered legacy, and **are likely to be removed in one of the future releases**.
283
+
如果你之前使用过 React,你可能了解过之前的 API 中的 string 类型的 ref 属性,例如 `"textInput"`。你可以通过 `this.refs.textInput` 来访问 DOM 节点。我们不建议使用它,因为 string 类型的 refs 存在 [一些问题](https://github.com/facebook/react/pull/8333#issuecomment-271648615)。它已过时并可能会在未来的版本被移除。
283
284
284
-
> Note
285
+
> 注意
285
286
>
286
-
> If you're currently using `this.refs.textInput`to access refs, we recommend using either the [callback pattern](#callback-refs) or the [`createRef` API](#creating-refs)instead.
### Caveats with callback refs {#caveats-with-callback-refs}
289
+
### 关于回调 refs 的警告 {#caveats-with-callback-refs}
289
290
290
-
If the `ref`callback is defined as an inline function, it will get called twice during updates, first with `null` and then again with the DOM element. This is because a new instance of the function is created with each render, so React needs to clear the old ref and set up the new one. You can avoid this by defining the `ref` callback as a bound method on the class, but note that it shouldn't matter in most cases.
0 commit comments