React中的純組件

React中的純組件

React提供了一種基於淺比較模式來肯定是否應該從新渲染組件的類React.PureComponent,一般只須要繼承React.PureComponent就能夠定義一個純組件。React.PureComponentReact.Component很類似,二者的區別在於React.Component並未實現shouldComponentUpdate(),而React.PureComponent中以淺層對比propstate的方式來實現了該函數。若是賦予React組件相同的propsstaterender()函數會渲染相同的內容,那麼在某些狀況下使用React.PureComponent可提升性能。javascript

描述

首先咱們來回顧下React組件執行重渲染re-render更新的時機,通常當一個組件的props屬性或者state狀態發生改變的時候,也就是父組件傳遞進來的props發生變化或者使用this.setState函數時,組件會進行從新渲染re-render。而在接受到新的props或者state到組件更新之間會執行其生命週期中的一個函數shouldComponentUpdate,當該函數返回true時纔會進行重渲染,若是返回false則不會進行重渲染,在這裏shouldComponentUpdate默認返回true,所以當組件遇到性能瓶頸的時候能夠在shouldComponentUpdate中進行邏輯判斷,來自定義組件是否須要重渲染。
咱們能夠稍微查看一下源碼的實現,能夠看到PureComponent是經過寄生組合繼承的方式繼承了Componentcommit id 0cf22a5html

// 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中以淺層對比propstate的方式來實現了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()僅做對象的淺層比較。若是對象中包含複雜的數據結構,則有可能由於沒法檢查深層的差異,產生錯誤的比對結果。僅在你的propsstate較爲簡單時才使用React.PureComponent,或者每次更新都使用新的對象,或者在深層數據結構發生變化時調用forceUpdate()來確保組件被正確地更新,你也能夠考慮使用immutable對象加速嵌套數據的比較。此外React.PureComponent中的shouldComponentUpdate()將跳過全部子組件樹的prop更新,所以須要確保全部子組件也都是純的組件。react

優勢

  • shouldComponentUpdate生命週期作了優化會自動shadow diff組件的stateprops,結合immutable數據就能夠很好地去作更新判斷。
  • 隔離了父組件與子組件的狀態變化。

缺點

  • shouldComponentUpdate中的shadow diff一樣消耗性能。
  • 須要確保組件渲染僅取決於propsstate

每日一題

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
相關文章
相關標籤/搜索