目錄
- 虛擬DOM
- ref的使用
虛擬DOM
當(dāng)組件的state或者props發(fā)生改變時(shí),render函數(shù)就會(huì)重新執(zhí)行。當(dāng)父組件的render函數(shù)被運(yùn)行時(shí),它的子組件的render都將被重新運(yùn)行。
React渲染機(jī)制:
1.state 數(shù)據(jù)
2.JSX模版
3.數(shù)據(jù) + 模版結(jié)合,生成虛擬DOM.['div', {id: 'abc', ['span', {}, 'hello world']}]
虛擬DOM是一個(gè)JS對(duì)象
4.用虛擬DOM的結(jié)構(gòu)生成真實(shí)的DOM,顯示.<div id='abc'><span>hello world</span></div>
5.當(dāng)state 發(fā)生變化后
6.數(shù)據(jù) + 模版 生成新的虛擬DOM['div', {id: 'abc', ['span', {}, 'bye-bye']}]
7.比較原始虛擬DOM和新的虛擬DOM的區(qū)別,找到區(qū)別是span中的內(nèi)容(Diff算法)
8.直接操作DOM,改變span中的內(nèi)容
整個(gè)過程為:JSX -> React.createElement -> 虛擬DOM (JS 對(duì)象 )-> 真實(shí)的DOM
引入虛擬DOM的好處:
- 性能提升,從DOM比對(duì)變成了JS比對(duì)
- 它使得跨端應(yīng)用得以實(shí)現(xiàn)。React Native
虛擬DOM中的Diff算法
1.setstate為什么是異步的?
性能優(yōu)化,將多次setState合成一次setState,減少虛擬DOM比對(duì)。
2.Diff進(jìn)行同層比對(duì),逐層去比對(duì),如果發(fā)現(xiàn)不同,直接替換,其后面的子
層全部廢棄。
3.為什么做列表循環(huán)的時(shí)候要引入key值?
提高虛擬DOM比對(duì)的性能,但是key值要保持穩(wěn)定,不要用index做key值
ref的使用
在react中可以使用ref來獲取dom元素。
<input
ref={(input) => {this.input=input}}
value={this.state.inputValue}
onChange={this.handleInputChange}/>
handleInputChange()
通過e.target
獲取input的value值,也可修改為const value = this.input.value
但要注意的是:
當(dāng)ref和setState一起使用的時(shí)候,要把操作dom的語法放在setState的第二個(gè)參數(shù)的函數(shù)里面,因?yàn)閟etState是異步函數(shù)。這樣就可以保證操作dom的方法是在頁面渲染后執(zhí)行的。
handleBtnClick () {
this.setState((prevState) => ({
list: [...prevState.list, prevState.inputValue],
inputValue: ''
}), () => {
console.log(this.ul.querySelectorAll('div').length)
})
}
如果將console.log(this.ul.querySelectorAll('div').length)
放在setState后面,就會(huì)出現(xiàn)下面的情況,獲取到的div總是比實(shí)際少一個(gè)。
(完)