React的Refs方法獲取DOM例項 和 訪問子元件方法及屬性

小弟調調發表於2016-08-13

React 支援一種非常特殊的屬性 Ref ,你可以用來繫結到 render() 輸出的任何元件上。

  • ref : 繫結屬性

  • refs : 呼叫的時候使用

呼叫子元件方法

這是一個很神奇的方法refs,它可以呼叫子元件的方法以及屬性。下面用一個例子來實現呼叫子元件方法。

建立元件

建立子元件MyComponent.js,並在子元件實現一個方法,如:subHandleClick,這個方法實現變更當前元件上面的文字,提供這樣一個測試用例。

使用子元件

通過import SubComponent from `./SubComponent`來引用子元件SubComponent,在 render方法中註冊使用元件

render(){
  return(
    <SubComponent/>
  )
}

繫結ref屬性

在子元件呼叫上面繫結一個值為subcomponents的屬性refsubcomponents

<SubComponent ref="subcomponents" />

呼叫子元件方法

在入口父元件App.js中,新增方法handleClick,去呼叫子元件SubComponent.js中的subHandleClick方法

handleClick(){
  //this.refs.subcomponents可以訪問子元件的方法
  //也可以獲取子元件的state...
  this.refs.subcomponents.subHandleClick();
}

完整例項

入口父元件App.js

import React, { Component } from `react`;
import SubComponent from `./SubComponent`
class MyComponent extends Component {
  handleClick(){
    this.refs.subcomponents.subHandleClick();
  }
  render(){
    return(
      <div>
        <input
          type="button"
          value="點我呼叫子元件方法"
          onClick={this.handleClick.bind(this)}
        />
        <SubComponent ref="subcomponents" />
      </div>
    )
  }
}

ReactDOM.render(
  <MyComponent/>, 
  document.querySelector(`#app`)
);

子元件SubComponent.js

import React, { Component } from `react`;
export default class SubComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      text: `這裡是初始化文字`
    };
  }
  subHandleClick(){
    this.setState({text: `文字被改變啦!哈哈!`})
  }
  render(){
    return(
      <div>
        檢視:{this.state.text}
      </div>
    )
  }
}

訪問父元件方法

父元件Parent.js

class Parent extends React.Component{
  constructor(props){
    super(props);
    this.state = {
     value:""
    }
  }
  refresh(){
    // 這裡箭頭函式很重要
    return ()=>{
        this.setState({value:"這裡是子元件呼叫的方法"})
    }
  }
  render(){
    return (
      <div>
        <h2>兄弟元件溝通</h2>
        <Brother refresh={this.refresh()}/>
        <p>{this.state.value}</p>
      </div>
    )
  }
}

ReactDOM.render(<Parent />, document.getElementById(`app`));

子元件SubComponent.js

import React, { Component } from `react`;
export default class SubComponent extends Component {
  constructor(props) {
    super(props);
  }
  subHandleClick(){
    this.setState({text: `文字被改變啦!哈哈!`})
  }
  render(){
    return(
      <div>
        <button onClick={this.props.refresh}>
            更新父元件
        </button>
      </div>
    )
  }
}

獲取DOM例項

通過ref屬性,你可獲取,例項中的屬性方法,甚至可以通過他獲取到DOM例項節點this.refs.myInput.getDOMNode()

ref 屬性繫結

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

refs 獲取DOM例項

獲取支撐例項( backing instance )。這樣就可以確保在任何時間總是拿到正確的例項。

// 輸入框獲取焦點
this.refs.myInput.focus()

完整例項

import React, { Component } from `react`;
class MyComponent extends Component {
  handleClick(){
    this.refs.myInput.focus();
  }
  render(){
    return(
      <div>
        <input 
          type="text" 
          ref="myInput" 
        />
        <input
          type="button"
          value="點我輸入框獲取焦點"
          onClick={this.handleClick.bind(this)}
        />
      </div>
    )
  }
}

ReactDOM.render(
  <MyComponent/>, 
  document.querySelector(`#app`)
);

相關文章