React.js 小書 Lesson21 - ref 和 React.js 中的 DOM 操作
轉載請注明出處籽暇,保留原文鏈接以及作者信息
在線閱讀:http://huziketang.com/books/react
在 React.js 當中你基本不需要和 DOM 直接打交道蛉顽。React.js 提供了一些列的 on*
方法幫助我們進行事件監(jiān)聽霹购,所以 React.js 當中不需要直接調(diào)用 addEventListener
的 DOM API;以前我們通過手動 DOM 操作進行頁面更新(例如借助 jQuery)郁油,而在 React.js 當中可以直接通過 setState
的方式重新渲染組件同规,渲染的時候可以把新的 props
傳遞給子組件,從而達到頁面更新的效果咧擂。
React.js 這種重新渲染的機制幫助我們免除了絕大部分的 DOM 更新操作逞盆,也讓類似于 jQuery 這種以封裝 DOM 操作為主的第三方的庫從我們的開發(fā)工具鏈中刪除。
但是 React.js 并不能完全滿足所有 DOM 操作需求松申,有些時候我們還是需要和 DOM 打交道云芦。比如說你想進入頁面以后自動 focus 到某個輸入框碴巾,你需要調(diào)用 input.focus()
的 DOM API痛垛,比如說你想動態(tài)獲取某個 DOM 元素的尺寸來做后續(xù)的動畫盒件,等等寸潦。
React.js 當中提供了 ref
屬性來幫助我們獲取已經(jīng)掛載的元素的 DOM 節(jié)點,你可以給某個 JSX 元素加上 ref
屬性:
class AutoFocusInput extends Component {
componentDidMount () {
this.input.focus()
}
render () {
return (
<input ref={(input) => this.input = input} />
)
}
}
ReactDOM.render(
<AutoFocusInput />,
document.getElementById('root')
)
可以看到我們給 input
元素加了一個 ref
屬性琉历,這個屬性值是一個函數(shù)坠七。當 input
元素在頁面上掛載完成以后,React.js 就會調(diào)用這個函數(shù)旗笔,并且把這個掛載以后的 DOM 節(jié)點傳給這個函數(shù)彪置。在函數(shù)中我們把這個 DOM 元素設置為組件實例的一個屬性,這樣以后我們就可以通過 this.input
獲取到這個 DOM 元素蝇恶。
然后我們就可以在 componentDidMount
中使用這個 DOM 元素拳魁,并且調(diào)用 this.input.focus()
的 DOM API。整體就達到了頁面加載完成就自動 focus 到輸入框的功能(大家可以注意到我們用上了 componentDidMount
這個組件生命周期)撮弧。
我們可以給任意代表 HTML 元素標簽加上 ref
從而獲取到它 DOM 元素然后調(diào)用 DOM API潘懊。但是記住一個原則:能不用 ref
就不用。特別是要避免用 ref
來做 React.js 本來就可以幫助你做到的頁面自動更新的操作和事件監(jiān)聽贿衍。多余的 DOM 操作其實是代碼里面的“噪音”授舟,不利于我們理解和維護。
順帶一提的是贸辈,其實可以給組件標簽也加上 ref
释树,例如:
<Clock ref={(clock) => this.clock = clock} />
這樣你獲取到的是這個 Clock
組件在 React.js 內(nèi)部初始化的實例。但這并不是什么常用的做法裙椭,而且也并不建議這么做,所以這里就簡單提及署浩,有興趣的朋友可以自己學習探索揉燃。
下一節(jié)中我們將介紹《React.js 小書 Lesson22 - props.children 和容器類組件》。