React 通過forwardRef獲取函數組件內某個DOM節點或者子組件的實例


在React當中,function組件返回的是一段jsx代碼,對於function組件本身來說,是沒有實例的,因此如果我們在引用一個function組件時如果設置了一個ref屬性是無效的,React還會做出一些檢查並給出錯誤提示,例如:

<div id="root"></div>    
<script type="text/babel">
  function MyComponent(props){                              //MyComponent是一個函數組件 return <input type="text"/>
  }
  class App extends React.Component{
    ref = React.createRef();
    
    componentDidMount(){
      console.log(this.ref.current)                         //掛載完成后打印this.ref.current
    }
    render(){
      return  <div><MyComponent ref={this.ref}/></div>      //引用函數組件時使用ref嘗試獲取該函數組件實例
    }
  }
  ReactDOM.render(<App/>,root)
</script>

執行后控制台輸出如下:

意思就是對於function組件來說,不能給他直接給他設置ref,另外打印出來的也是null

對於function組件來說,我們可以用React.forwardRef()來實現,具體的做法是把function組件作為參數傳遞給React.forwardRef(),然后function組件可以帶兩個參數,分別是props和ref,在function組件內部返回的jsx中可以給某個DOM節點或自組件設置ref屬性,值就是這個函數組件的參數二,例如:

function myComponent(props,refObj){
  return <div>
            <p ref={refObj}>123</p>        //這里refObj就是傳入的參數2了
          </div>
}

舉個栗子,和上一節的幾個ref例子實現的效果一樣,我們用函數組件也實現一個類似的效果,如下:

<div id="root"></div>    
<script type="text/babel">
  const MyComponent = React.forwardRef((props,ref)=>(                     //傳遞了一個props和ref屬性,我們先用props進行初始化
    <p ref={ref}>no:{props.no}</p>
  ))

  class App extends React.Component{
    state = {no:1}
    domp = React.createRef();
    
    test= ()=>{ this.domp.current.textContent = 'no:'+ ++this.state.no }   //之后點擊測試按鈕后就修改MyComponent組件內p元素的textContent

    render(){
      return  <div>
                <button onClick={this.test}>測試</button>
                <MyComponent no={this.state.no} ref={this.domp}/>          //這里指定ref屬性為this.ref,之后就可以通過this.domp來訪問MyComponent組件內的p節點對象了
              </div>
    }
  }
  ReactDOM.render(<App/>,root)
</script>

 writer by:大沙漠 QQ:22969969

效果和上一節的是一樣的,就不演示了,我們這里使用了props傳值進行初始化,之后點擊測試按鈕時就同構this.domp獲取到MyComponent組件內的p元素實例,然后通過原生的textContent屬性設置其文本內容。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM