【React】親コンポーネント更新による子コンポーネントの更新処理を減らす

Reactでは親コンポーネントが更新されると、その子コンポーネント全てに更新処理が走るのですが、値に変更がない子コンポーネントは更新処理を行わないようにできないものかと調べたら、良さそうな方法が見つかったので備忘録として残します。

参考:

ReactでshouldComponentUpdateを使ったチューニングの効果と注意どころ - Qiita Reactの再レンダリングをなるべく減らす - Aqutras Members' Blog

Reactコンポーネントの更新処理をキャンセルするためには、shouldComponentUpdate内でfalseを返してあげれば良い。(デフォルトではtrue) なので、子コンポーネントpropsstateに変更がなければ、shouldComponentUpdate内でfalseを返す処理を実装すれば、データの更新がない子コンポーネントの更新を行わないようにできる。

propsstateが全て値型か、参照型を含むかで異なる実装を行う。

全て値型の場合

react-addons-pure-render-mixinを使うと簡単に実装できて良い。

import PureRenderMixin from 'react-addons-pure-render-mixin';

class HogeComponent extends React.Component {
  constructor(props) {
    super(props);
    this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
  }

  render() {
    return (
      ...
    )
  }
}

値型だけでなく参照型を含む場合

lodashの _.isEqual 関数を用いてオブジェクトを比較する。 もちろん値型も見てくれるので、react-addons-pure-render-mixinを使わずに、この方法に統一しても良さそう。

import isEqual from 'lodash/isEqual';

class HogeComponent extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    const propsDiff = isEqual(nextProps, this.props);
    const stateDiff = isEqual(nextState, this.state);
    return !(propsDiff && stateDiff);
  }

  render() {
    return (
      ...
    )
  }
}

とりあえず今の自分の環境では↑の2通りの方法を使って実装しています。