1. 程式人生 > >React元件中的refs

React元件中的refs

var myComponent = ReactDOM.render(<MyComponent />, myContainer);

這裡,我們獲取的myComponent就是元件例項。注意,這個方法只是在頂級元件中有效。

2.The Ref Callback Attribute

當我們渲染一個元件時,可以給元件新增ref屬性,我們給這個屬性新增一個回撥方法,當元件渲染(mounted)完畢時,就會呼叫這個回撥函式。

  render: function() {
    return (
      <TextInput
        ref={function(input) {
          if (input != null) {
            input.focus();
          }
        }} />
    );
  },

可以看到,上邊的TextInput是我們的元件,ref屬性後邊賦予了一個函式,這就是回撥函式,傳入的引數就是我們的元件例項。

當我們在dom節點如div中新增ref屬性時,返回的是真實的dom節點,我們可以直接操作。

但是如果渲染的是元件的話,如上面的TextInput,我們只能呼叫在元件中定義的方法,上邊呼叫的focus()方法就是在TextInput元件中定義的方法。

如果我們想要獲取元件對應的瀏覽器中的物件,可以使用ReactDOM.findDOMNode(input)來獲取dom節點。

3.The Ref String Attribute

ref的另外一個使用方法就是給ref屬性一個字串,相當於給元件起了一個名字,渲染完成後,就可以使用this.ref.name的方式獲取元件類的例項。

同樣,如果是div一類的,獲取到的是dom節點。如果是自定義元件,獲取到的是元件類例項。

var App = React.createClass({
      componentDidMount : function(){
        var node1 = this.refs.myinput;
        var node2 = ReactDOM.findDOMNode(this.refs.myson);
      },
      render: function() {
        return (
        <div>
          <input ref="myinput" />
          <Son className="son" ref="myson"/>
        </div>
        );
      }
    });
以上就是ref的使用方法。

下面是文件中的一個例子:

var MyComponent = React.createClass({
  handleClick: function() {
    // Explicitly focus the text input using the raw DOM API.
    if (this.myTextInput !== null) {
      this.myTextInput.focus();
    }
  },
  render: function() {
    // The ref attribute is a callback that saves a reference to the
    // component to this.myTextInput when the component is mounted.
    return (
      <div>
        <input type="text" ref={(ref) => this.myTextInput = ref} />
        <input type="button" value="Focus the text input" onClick={this.handleClick}/>
      </div>
    );
  }
});

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

可以看到,在MyComponent中的input的ref是一個回撥函式,在回撥函式中將this.myTextInut賦予了返回的例項(this的指向就是當前的MyConponent例項),之後,又在下一個input點選響應事件函式中呼叫了這個例項物件。

下面來翻譯一下文件中的summary,有助於我們理解ref到底是做什麼的。(注:可能不十分正確,但大意應該沒錯)

Refs are a great way to send a message to a particular child instance in a way that would be inconvenient to do via streaming Reactive props and state.

如果你覺得依靠互動性的props和state向某個特定子例項中傳遞訊息不是很好的方式的話,refs是一個很好的解決辦法。

They should, however, not be your go-to abstraction for flowing data through your application.

ref不應該成為你的應用中抽象的傳遞資料的方法。

By default, use the Reactive data flow and save refs for use cases that are inherently non-reactive.

所以,在應用互動資料流的同時,refs適合於那些非互動性的例項。

補充一點:ref在stateless function中沒法用的。

什麼是stateless function呢?

function HelloMessage(props) {
  return <div>Hello {props.name}</div>;
}
var ins = ReactDOM.render(<HelloMessage name="Sebastian" />, mountNode);

HelloMessage就是一個stateless function。同時,這裡的ins也是null。

This simplified component API is intended for components that are pure functions of their props. These components must not retain internal state, do not have backing instances, and do not have the component lifecycle methods.

這是文件中對sateless function的解釋。

它是一個只依靠傳遞下來的props的純函式,它們不包含state,例項,也沒有元件生命週期對應的方法。

In an ideal world, most of your components would be stateless functions because in the future we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations. This is the recommended pattern, when possible.

文件的最後說道,在理想情況下,你的大部分的元件都應該是stateless function,這也是設計人員所憧憬的情況。