React DOM操作

 2016年02月13日    3798     声明


大多数情况下,我们并不需要直接操作真实的DOM,React 的虚拟DOM足以满足创建用户界面的需要。而在极少数情况下,我们又不得不去操作底的DOM。为了和浏览器交互,我们需要获取对DOM节点的引用,React 提供了一个访问受自身控制的DOM节点(已挂载组件)的方法getDOMNode,通过这个方法我们可以在组件挂载后访问底层 DOM。


  1. refs属性
  2. findDOMNode方法与getDOMNode方法
  3. 内部访问与外部访问
  4. 可访问DOM的组件生命周期


1. refs属性

受控的DOM节点是指由在React 组件挂载后,React 组件由生成的DOM节点。要访问这些DOM节点,首先需要获取对这些节点的引用,这时我们需要为组件设置一个ref属性。ref可以是一个字符串,可用于任何由render()方法返回的组件实例。ref做为字符串时,相当于一个组件ID,所以其值必须是唯一的。

设置该refs属性后,我们就可以在组件内部通过this.refs或通过findDOMNode()查找组件生成的DOM。

render()方法中设置refs属性:

<input type="text" ref="myInput" />

设置refs属性可以通过this.refs获取对组件的引用:

this.refs.myInput

或者使用findDOMNode查找DOM:

React.findDOMNode(this.refs.myInput)


ref 回调属性

ref属性可是一个回调函数,该函数会在组件挂载后立即执行,被引用的组件会做为参数传入回调函数中:

<input ref={ function(component){ React.findDOMNode(component).focus();} } />


2. findDOMNode方法与getDOMNode方法

findDOMNodeReactDOM类库提供的一个类方法。该方法可以在组件内部或外部获取对组件生成的底层DOM的引用。

getDOMNode是React组件的实例方法,该方法可以获取组件实例生成的DOM引用。

findDOMNodegetDOMNode方法都会返回一个DOM元素(DOMElement),但findDOMNode方法找不到元素生成的DOM元素时,可能会返回NULL

示例:使用findDOMNodegetDOMNode访问底层DOM:

var MyInput = React.createClass({
  handleClick: function() {
    // 使用getDOMNode方法访问底层的API
    this.refs.myInput.getDOMNode().focus();
  },
  componentDidMount: function() {
    // 使用findDOMNode方法访问底层的API
    ReactDOM.findDOMNode(this.refs.myInput).value = 'itbilu.com';
  },
  render: function() {
    return <input type="text" ref="myInput" />;
  }
});

ReactDOM.render(
  <MyInput />,
  document.getElementById('example')
);


3. 内部访问与外部访问

上面介绍了通过通过组件的refs属性访问组件生成的底层DOM,使用refs属性访问组件,是组件的内部访问

在实际应中,可能还会外部访问组件。外部访问组件生成的DOM,要通过ReactDOM.render()方法返回的组件实例获取对组件的引用:

var MyInput = React.createClass({
  render: function() {
    return <input type="text" />;
  }
});

var myInput = ReactDOM.render(
  <MyInput />,
  document.getElementById('example')
);

// 使用findDOMNode()方法外部访问组件
ReactDOM.findDOMNode(myInput).value = 'itbilu.com';

// 使用getDOMNode()方法外部访问组件
myInput.getDOMNode().focus();


4. 可访问DOM的组件生命周期

要访问底层DOM要在DOM创建完成后,即:组件挂载完成后。componentDidMount并不是底层DOM的唯一的访问环境,在componentDidMount挂载完成后,及组件生命周期的存在期、销毁&清理期都可以访问。


注意refsgetDOMNode会造React性能的降低,且会增加应用的复杂性。所以,应该只在虚拟DOM无法完成时才考虑使用。