1). Component存在的問題?
a. 父組件重新render(), 當前組件也會重新執行render(), 即使沒有任何變化
b. 當前組件setState(), 重新執行render(), 即使state沒有任何變化
測試代碼如下,首先是a情況
/**父組件 */ import React, { Component } from 'react' import Child from './Child' class Parent extends Component { state = { money:100 } changeFn = () => { this.setState(state=>({ money:state.money+1 })) } render() { console.log('parent render') return ( <> <h2>parent組件:{this.state.money}</h2> <button onClick={this.changeFn}>Parent測試</button> <Child></Child> </> ); } } export default Parent;
/**子組件 */
import React, { Component } from 'react'
class Child extends Component {
state = {
money:100
}
changeFn = () => {
this.setState(state=>({
money:state.money+1
}))
}
render() {
console.log('child render')
return (
<>
<h2>child組件:{this.state.money}</h2>
<button onClick={this.changeFn}>Child測試</button>
</>
);
}
}
export default Child;
此時修改父組件

如果父組件傳入子組件狀態,狀態更新,兩者都更新,這符合正常邏輯,如下所示。但上述的兩者並不存在狀態繼承

b情況測試如下:

此時state並沒有更新,但還是觸發了render。
這里的問題便涉及到react生命周期相關,鈎子圖如下

局部放大我們查看下

這里shouldcomponentUpdate默認值為true,所以會往下執行更新流程。如下所示

b. 辦法1: 重寫shouldComponentUpdate(), 判斷如果數據有變化返回true, 否則返回false c. 辦法2: 使用PureComponent代替Component d. 說明: 一般都使用PureComponent來優化組件性能
重寫方案進行優化完整如下

此時測試如下,子組件點擊時不再render

但是目前為止state都是基本數據類型,如果較為復雜時則該方案較難比較,需要自行進行依次對比----淺比較.
2). 解決Component存在的問題
a. 原因: 組件的shouldcomponentUpdate()默認返回true, 即使數據沒有變化render()都會重新執行
b. 辦法1: 重寫shouldComponentUpdate(), 判斷如果數據有變化返回true, 否則返回false
c. 辦法2: 使用PureComponent代替Component
d. 說明:
一般都使用PureComponent來優化組件性能
3). PureComponent的基本原理
如下所示
此時便解決了以上問題
a. 重寫實現shouldComponentUpdate()
b. 對組件的新/舊state和props中的數據進行淺比較, 如果都沒有變化, 返回false, 否則返回true
c. 一旦componentShouldUpdate()返回false不再執行用於更新的render()
這里可以結合項目角色授權組件進行測試。
測試發現沒有更新子組件,關閉時父組件render,子組件也會觸發render。修改如下

4). 面試題:
組件的哪個生命周期勾子能實現組件優化?
PureComponent的原理?
區別Component與PureComponent?
5)PureComponent使用注意:
如果組件內部的state為對象或數組格式,當該對象或數組內部發生改動時,不能直接獲取setState,這里必須使用解構賦值,將對象或數組內部展開,再重新賦值,才會改動
1、該寫法無效,不會觸發更新

2、解構賦值展開內部才會觸發更新

所以為了避免不必要問題,盡量多用解構賦值寫法。
***
PureComponent使用注意事項:
即如果改變的是數組或對象內部的某個狀態,則必須使用解構賦值語法重新setState,否則不會更新
***.
.
