在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屬性設置其文本內容。