用生命谱写代码的赞歌

0%

关于 React 的 this.refs 用法

Refs

ref 是 reference 的简称,在 React 中表示父组件引用子组件。

组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM。只有当它插入文档以后,才会变成真实的 DOM。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM 上,这种算法叫做 DOM diff,它可以极大提高网页的性能表现。但是,我们有时需要从组件获取真实 DOM 的节点,这时就要用到 ref 属性。

this.refs[refName]

this.refs.[refName] 返回真实的 DOM 节点。需要注意的是,由于 this.refs.[refName] 属性获取的是真实 DOM,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MyComponent extends React.Component{
handleClick(event){
this.refs.myInput.focus();
}
render(){
return (
<div>
<input type="text" ref="myInput" />
<button onClick={this.handleClick}>Focus on me</button>
</div>
)
}
}
React.render(<MyComponent/>,document.body)

ref 是函数

ref 属性可以是一个回调函数,而不是一个名字。这个回调函数在组件挂载后立即执行。被引用的组件作为一个参数传递,且回调函数可以立即使用这个组件,或保存供以后使用(或实现这两种行为)。比如下面这段代码,ref 回调储存 DOM 节点的引用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.focus = this.focus.bind(this);
}

focus() {
// Explicitly focus the text input using the raw DOM API
this.textInput.focus();
}

render() {
// Use the `ref` callback to store a reference to the text input DOM
// element in this.textInput.
return (
<div>
<input
type="text"
ref={(input) => { this.textInput = input; }} />
<input
type="button"
value="Focus the text input"
onClick={this.focus}
/>
</div>
);
}
}

React 将在组件 mount 时调用 ref 回调,输入 DOM 元素;在组件 unmount 时调用 ref 回调,输入 null。一种常见的模式是利用 ref 回调来访问 DOM 元素。如果你现在使用的是 this.refs.refName 来访问 ref,建议采用上面这种回调函数的形式。

当 ref 属性用在一个自定义组件上,ref 回调接受这个组件的 mounted 实例作为参数。比如,如果我们想包裹上面的 CustomTextInput 组件来模拟它 mount 后立即被单击。

1
2
3
4
5
6
7
8
9
10
11
class AutoFocusTextInput extends React.Component {
componentDidMount() {
this.textInput.focus();
}
render() {
return (
<CustomTextInput
ref={(input) => { this.textInput = input; }} />
);
}
}

你可能不会在函数组件上使用 ref 属性,因为函数组件没有实例,然而你可以在函数组件的 render 函数中使用ref属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function CustomTextInput(props) {
// textInput must be declared here so the ref callback can refer to it
let textInput = null;

function handleClick() {
textInput.focus();
}

return (
<div>
<input
type="text"
ref={(input) => { textInput = input; }} />
<input
type="button"
value="Focus the text input"
onClick={handleClick}
/>
</div>
);
}

不要滥用 refs

当你想使用 refs 时,想想是否可以用 state 代替。最适合设置 state 的地方是在层级中较高的位置设置

原文地址