您的位置:首页 > Web前端 > React

React refs

2016-03-04 13:18 585 查看
来源:七、获取真实的DOM节点

组件并不是真实的
DOM
节点,而是存在于内存之中的一种数据结构,叫做
虚拟 DOM
virtual DOM
)。

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

var MyComponent = React.createClass({
handleClick: function () {
this.refs.String.getDOMNode().focus();
},
render: function () {
console.log(2);
return (
<div>
<input type="text" ref="String"/>
<button type="button" onClick={this.handleClick}>Search</button>
</div>
)
}

});

console.log(1);
React.render(
<MyComponent />,
document.getElementById("demo"),
function () {
console.log('done');
}
);

console.log(3);

//依次输出1,2,done,3


组件
MyComponent
的子节点有一个文本输入框,用于获取用户的输入。这时就必须获取真实的
DOM
节点,虚拟
DOM
是拿不到用户输入的。

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

上面代码中,通过为组件指定
Click
事件的回调函数,确保了只有等到真实
DOM
发生
Click
事件之后,才会读取
this.refs.[refName]
属性。

React
组件支持很多事件,除了
Click
事件以外,还有
KeyDown
Copy
Scroll
等 。

来自官网文档描述

在从
render
方法中返回
UI
结构之后,你可能想冲出
React
虚拟
DOM
的限制,在
render
返回的组件实例上调用某些方法。

通常来说,这样做对于应用中的数据流动是不必要的,因为活跃的数据(
Reactive data
)流总是确保最新的
props
被传递到每一个从
render()
输出的子级中去。

注意:记住,从
render()
中返回的内容并不是实际渲染出来的子组件实例。从
render()
返回的仅仅是子组件层级树实例在特定时间的一个描述。

这意味着千万不要紧紧抓住
render()
返回的东西不放,然后还一厢情愿地希望生成自己想象中的东西

this.refs.[refName].getDOMNode()
直接获取到组件的 DOM 节点。

优点:

1、可以在组件类里面定义任何公共的方法(比如在输入之前的重置方法),然后通过
refs
来调用这些公共的方法(比如
this.refs.myTypeahead.reset()
)。

2、管理
DOM
几乎总是需要冲出“本地”组件的限制,比如通过
this.refs.myInput.getDOMNode()
获取
input
元素的底层
DOM
节点。
Refs
是做这件事唯一可靠的方式。

3、
Refs
是被自动管理的!如果某个子级实例被销毁了,它的
ref
也会自动销毁。不用考虑内存问题(除非你自己做一些疯狂的操作,保存了什么引用)。

当心:

绝不要在任何组件的
render
方法中访问
refs
- 或者在某个组件的
render
方法正在调用堆栈中运行的时候。

you must access using this.refs[‘myRefString’] if your ref was defined as ref=”myRefString”.

var App = React.createClass({
getInitialState: function () {
return {userInput: ''};
},
handleChange: function (e) {
this.setState({userInput: e.target.value});
},
clearInput: function () {
// Clear the input
this.setState({userInput: ''}, function () {
this.refs.theInput.getDOMNode().focus();
});
},
render: function () {
return (
<div>
<input type="text" ref="theInput" value={this.state.userInput} onChange={this.handleChange}/>
<button type="button" onClick={this.clearInput}>Click to Focus and Reset</button>
</div>
)
}
});

React.render(
<App />,
document.getElementById('demo2')
)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: