我想說的是
ref 一時爽,維護火葬場
setState 有 callBack 函數
有些時候會希望對 DOM 上面的值做操作,或是直接取得某個 input 欄位的 value
但是 react 本身就是 virtual DOM,是沒辦法直接抓到值的
也有可能是之前的人覺得程式寫得太不白話,所以給了一個語意化的代稱
為了解決這個問題呢,React 提供了 ref 的概念
使用 ref 就可以抓到 react DOM 中的元素
看看範例中,e 不太好懂是什麼東西
inputChange(e){
this.setState({
inputValue:e.target.value
})
}
若是在父層綁定 ref
<input
id="input_box"
className="input"
value={this.state.inputValue}
onChange={this.inputChange.bind(this)}
ref={(input)=>{this.input=input}}
/>
則可以直接呼叫
inputChange(){
this.setState({
inputValue:this.input.value
})
}
看起來直觀很多,ref 屬性也適用在子組件,讓父組件可以存取到子組件
但是由於 React 的是數據驅動的,所以用 ref 會出現各種問題
以及另一個坑是在React 中 setState
是一個異步執行函數
如果直接在 setState 後面使用 ref 抓取 DOM 內容的話,還沒等到新的 DOM 被渲染
就會開始執行後面的內容,進而發生錯誤
例如以下我們加入新的內容後印出當前的 div 內容長度
addList(){
this.setState({
list:[...this.state.list,this.state.inputValue],
inputValue:''
})
console.log(this.ul.querySelectorAll('div').length)
}
實際執行會發現,怎麼數量不太對?總是少了一個
也就是因為 setState 執行是需要時間的,還沒等虛擬 DOM 渲染完成
下方的 console.log 就已經執行了
而為了解決這個問題,其實 setState 具有一個 callback 函數
寫成下面這樣就會動了,也就是說在執行完之後再執行 console.log
addList(){
this.setState({
list:[...this.state.list,this.state.inputValue],
inputValue:''
},()=>{
console.log(this.ul.querySelectorAll('div').length)
})
}
可以在網路上找到一堆關於 React ref 的發問
通常最後結果都是 你不應該在這邊用 ref
,所以平常就盡量少用這個東西
這邊就是關於 ref
的一些介紹