React中的Refs

在典型的React數據流中, props是父組件和子組件交互的惟一方式,要修改一個子組件,你須要使用新的props來從新渲染它。可是在某些狀況下,你須要在典型的數據流以外強制修改子組件、或獲取組件的屬性值。被修改的子組件多是一個React組件的實例,也多是一個DOM元素。html

Refs提供了一種容許咱們訪問DOM節點或在render方法中建立的React元素的方式。數組

經過React.crateRef()建立

Refs可使用React.createRef()建立,並經過ref屬性附加到React元素。在構造組件時,一般將Refs分配給實例屬性,以即可以在整個組件中調用. ref做爲原生DOM的屬性傳入bash

class Index extends React.Component {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef();
    this.getInput = this.getInput.bind(this);
  }

  componentDidMount() {
    console.log(this.componentRef.current)
  }

  getInput() {
    console.log(this.inputRef.current.value)
  }

  render() {
    return (
      <div>
        <input ref={this.inputRef}/>
        <button onClick={this.getInput}>getValue</button>
      </div>
    )
  }
}
複製代碼

不過此例子並不恰當,在實際運用中能經過狀態申明的方式解決,就避免使用refref做爲組件的屬性傳入函數

class IndexPage extends React.PureComponent{
  constructor(props) {
    super(props);
    this.componentRef = React.createRef()
  }

  componentDidMount() {
    console.log(this.componentRef.current)
  }
  
  render() {
    return (
      <div>
        <Ref ref={this.componentRef} />
      </div>
    );
  }
}
複製代碼

ref傳遞給render中的元素時,對該節點的引用能夠經過生成的Refs對象的current屬性訪問。但current屬性的值因節點的類型不一樣而有所不一樣。ui

  • ref做用於html元素時,構造函數中使用React.createRef()建立的ref接收底層DOM元素做爲其current屬性的值。
  • ref做用於class申明的React組件時,構造函數中使用React.createRef()建立的ref接收組件實例做爲其current屬性的值。
  • 函數組件因爲沒有實例,因此不能給其添加ref屬性,系統會警告
    React會在組件掛載時,將DOM元素或組件的實例傳遞給current屬性,在組件卸載時給current屬性值傳入 null,ref會在 componentDidMount 或 componentDidUpdate 生命週期鉤子函數觸發前更新。

回調函數建立

refs能夠經過回調函數的形式建立,它能助你更精細地控制什麼時候refs被設置和解除。 回調函數接收DOM元素或React組件實例做爲參數,並將該參數添加到實例屬性上,以使它們能在其餘地方被存儲和訪問。回調函數形式建立的ref,經過回調函數的參數直接引用不須要經過current。 ref做爲原生DOM的屬性傳入this

class Index extends React.Component {
  constructor(props) {
    super(props);
    this.setInputRef = el => {
      this.inputRef = el
    };
    this.getInput = this.getInput.bind(this);
  }
  getInput() {
    console.log(this.inputRef)
  }
  render() {
    return (
      <div>
        <input ref={this.setInputRef} />
        <button onClick={this.getInput}>getValue</button>
      </div>
    )
  }
}
複製代碼

ref做爲組件的屬性傳入spa

class IndexPage extends React.PureComponent{
  constructor(props) {
    super(props);
  }

  componentDidMount() {
    console.log(this.componentRef)
  }
  
  render() {
    return (
      <div>
        <CallBackRef ref={ el => {this.componentRef = el}} />
      </div>
    );
  }
}
複製代碼

ref做爲原生DOM的屬性傳入時回調函數的參數便是該DOM對象,ref做爲組件的屬性傳入時,回調函數的參數便是該React組件的實例對象。React將在組件掛載時,會調用ref回調函數並傳入對象參數。在 componentDidMount 或 componentDidUpdate 觸發前,React 會保證 refs 必定是最新的。code

字符串建立

當組件插入到 DOM 後,ref屬性添加一個組件的引用於到 this.refs,經過this.refs.xxx獲取對節點的引用component

class Index extends React.Component {
  constructor(props) {
    super(props);
    this.getInput = this.getInput.bind(this);
  }
  getInput() {
    console.log(this.refs.inputRef)
  }
  render() {
    return (
      <div>
        <input ref="inputRef" />
        <button onClick={this.getInput}>getValue</button>
      </div>
    )
  }
}
複製代碼

在React16.3以後的版本中該方法已經棄用,建議使用前兩種。cdn

相關文章
相關標籤/搜索