1.ref
可以挂载到组件上也可以是dom元素上;
- 挂到有状态组件(
class
声明的组件,React.Component)上的ref表示对组件实例的引用。不能在无状态组件(函数式组件)上使用 ref 属性,因为它们没有实例。
如何区分有状态和无状态组件:
// 有状态组件
class App extends Component{
render() {
return(......);
}
}
export default App;
// 无状态组件
const person= (props)=>{
return(......)
}
反面教材:
//MyInput为无状态组件
function MyInput() {
return <input />;
}
class Parent extends React.Component {
render() {
return (
<MyInput
ref={(input) => { this.textInput = input; }} />
);
}
}
上面的代码是无法正常工作的。
- 挂载到dom元素上时表示具体的dom元素节点。
如:<input>,<a>
2.ref挂载的方式分为两种:
a.字符串
例如:
<input ref='myInput' />
通过this.refs.myInput方式可获取到节点。
b.回调函数
例如:
<input ref={(ref)=>{this.myInput = ref}} /> //推荐使用
通过this.myInput,我们就可以对<input />
进行一系列操作,比如让输入框聚焦:
this.myInput.focus();
两种挂载方式都可以通过ReactDOM.findDOMNode(ref)来获取组件挂载后真正的dom节点。但是对于dom元素使用ref的情况,ref本身引用的就是该元素的实际dom节点,无需使用ReactDOM.findDOMNode(ref)来获取,该方法常用于React组件上的ref。
3.使用this.refs与ReactDOM.findDOMNode方法的对比
- ref添加到组件上获取的是组件实例,添加到原生HTML上获取的是DOM;
ReactDOM.findDOMNode
,当参数是DOM,返回值就是该DOM;当参数是组件获取的是该组件的render方法中的DOM- 二者主要区别在ref绑定在组件上的时候,
this.refs
获取到的是组件实例,ReactDOM.findDOMNode
获取到的是dom节点。
参考代码如下:
var Parent = React.createClass({
render: function(){
return (
<div className = 'parent'>
<Child ref = 'child'/>
</div>
)
},
componentDidMount(){
console.log(this.refs.child); // 访问挂载在组件上ref
console.log(this.refs.child.refs.update); // 访问挂载在dom元素上的ref
console.log(ReactDOM.findDOMNode(this.refs.child)); // findDOMNode获取ref
}
})
var Child = React.createClass({
render: function() {
return (
<div ref="test">
<a ref="update">更新</a>
</div>
);
}
});
ReactDOM.render(
<Parent/>,
document.getElementById('example')
);
- 给 dom元素设置 ref
<a ref="update">更新</a>
后,可以拿到它的真实 dom<a>更新</a>
。 - 给组件设置ref
<Child ref = 'child'/>
后,拿到的是组件的实例(上图中的Constructor
) - 使用ReactDOM.findDOMNode可获取组件挂载后真正的dom节点。
注:当给组件、dom元素添加 ref 属性后,此实例只能在当前组件中被访问到,父组件的 refs 中是没有此引用的。