React
提供了一種基於淺比較模式來肯定是否應該從新渲染組件的類React.PureComponent
,一般只須要繼承React.PureComponent
就能夠定義一個純組件。React.PureComponent
與React.Component
很類似,二者的區別在於React.Component
並未實現shouldComponentUpdate()
,而React.PureComponent
中以淺層對比prop
和state
的方式來實現了該函數。若是賦予React
組件相同的props
和state
,render()
函數會渲染相同的內容,那麼在某些狀況下使用React.PureComponent
可提升性能。javascript
首先咱們來回顧下React
組件執行重渲染re-render
更新的時機,通常當一個組件的props
屬性或者state
狀態發生改變的時候,也就是父組件傳遞進來的props
發生變化或者使用this.setState
函數時,組件會進行從新渲染re-render
。而在接受到新的props
或者state
到組件更新之間會執行其生命週期中的一個函數shouldComponentUpdate
,當該函數返回true
時纔會進行重渲染,若是返回false
則不會進行重渲染,在這裏shouldComponentUpdate
默認返回true
,所以當組件遇到性能瓶頸的時候能夠在shouldComponentUpdate
中進行邏輯判斷,來自定義組件是否須要重渲染。
咱們能夠稍微查看一下源碼的實現,能夠看到PureComponent
是經過寄生組合繼承的方式繼承了Component
,commit id
爲 0cf22a5
。html
// master/packages/react/src/ReactBaseClasses.js line 123 // ... function ComponentDummy() {} ComponentDummy.prototype = Component.prototype; /** * Convenience component with default shallow equality check for sCU. */ function PureComponent(props, context, updater) { this.props = props; this.context = context; // If a component has string refs, we will assign a different object later. this.refs = emptyObject; this.updater = updater || ReactNoopUpdateQueue; } const pureComponentPrototype = (PureComponent.prototype = new ComponentDummy()); pureComponentPrototype.constructor = PureComponent; // Avoid an extra prototype jump for these methods. Object.assign(pureComponentPrototype, Component.prototype); pureComponentPrototype.isPureReactComponent = true; // ...
同時在checkShouldComponentUpdate
函數中有一段這樣的邏輯,在函數名上就能看出是對傳入的參數進行了一次淺比較,所以實際上PureReactComponent
組件和ReactComponent
組件的區別就是React.PureComponent
中以淺層對比prop
和state
的方式來實現了shouldComponentUpdate()
函數。java
// master/packages/react-reconciler/src/ReactFiberClassComponent.new.js line 334 // ... if (ctor.prototype && ctor.prototype.isPureReactComponent) { return ( !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) ); } // ...
須要注意的是,React.PureComponent
中的shouldComponentUpdate()
僅做對象的淺層比較。若是對象中包含複雜的數據結構,則有可能由於沒法檢查深層的差異,產生錯誤的比對結果。僅在你的props
和state
較爲簡單時才使用React.PureComponent
,或者每次更新都使用新的對象,或者在深層數據結構發生變化時調用forceUpdate()
來確保組件被正確地更新,你也能夠考慮使用immutable
對象加速嵌套數據的比較。此外React.PureComponent
中的shouldComponentUpdate()
將跳過全部子組件樹的prop
更新,所以須要確保全部子組件也都是純的組件。react
shouldComponentUpdate
生命週期作了優化會自動shadow diff
組件的state
和props
,結合immutable
數據就能夠很好地去作更新判斷。shouldComponentUpdate
中的shadow diff
一樣消耗性能。props
與state
。https://github.com/WindrunnerMax/EveryDay
https://zhuanlan.zhihu.com/p/30659051 https://juejin.cn/post/6844903618848669709 https://juejin.cn/post/6844904099679305741 https://segmentfault.com/a/1190000014979065 https://ginnko.github.io/2018/12/17/pure-component/ https://zh-hans.reactjs.org/docs/react-api.html#reactpurecomponent