過去在工作中,注意到過父組件採用了PureComponent這種形式,但是當時不求甚解,沒去細究過為何要使用它,和適用的場景。

今天看書的時候正好翻到React的性能優化這一節,通過一個demo對它的使用有了一些新的認識。

import React, {PureComponent} from react;

class TableList extends React.PureComponent {
constructor(props) {
super(props)
this.state = {
numbers: [1, 2, 3, 4]
}
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
const numbers = this.state.numbers
numbers.push(numbers[numbers.length - 1] + 1)
console.log(numbers, numbers)
this.setState({
numbers: numbers
})
}
render() {
return(
<div>
<button onClick={this.handleClick}/>
{this.state.numbers.map(item => <div key={item}>{item}</div>)}
</div>
)
}
}
export default TableList

這是一個普通的列表,輸出number中的元素為子項。

在點擊按鍵觸發添加子項的事件時候,如果使用pureComponent, state中的數據是會改變的,然而不會將更新渲染到視圖中。也就是說列表子項是不會增加的。

React的生命週期中存在一個叫做shouldComponentUpdate的方法,這個方法默認返回值是TRUE,如果返回false,組件此次更新就會停止,這樣能夠防止組件多次渲染造成性能上的多餘損耗。也就是 後續 的 componentWillUpdate、 render 等方法 都不會再被執行。

而PureComponent會使用淺比較來比較新舊的state和props,因此可以讓組件繼承PureComponent來代替手寫shouldComponentUpdate的邏輯。

在這個demo裡面, 因為我們是直接修改this.state.numbers數組,等於引用對象this.state.numbers在點擊前後都沒有改變過,所以shouldComponentUpdate返回為false,也就是不會渲染。

那麼,如果我們需要將更新渲染出來呢? 可以使用以下兩種方式

  1. 適用普通的React.Component來取代React.PureComponent
  2. 直接修改this.state.numbers ,而不是修改numbers的數組

順帶一提的是,在瞭解這個小問題的時候,又再次複習了生命週期的知識,並且對虛擬dom這個概念有了更加細緻的認識,真可謂是一舉多得呀

推薦閱讀:

相關文章