【React】親コンポーネント更新による子コンポーネントの更新処理を減らす
Reactでは親コンポーネントが更新されると、その子コンポーネント全てに更新処理が走るのですが、値に変更がない子コンポーネントは更新処理を行わないようにできないものかと調べたら、良さそうな方法が見つかったので備忘録として残します。
参考:
ReactでshouldComponentUpdateを使ったチューニングの効果と注意どころ - Qiita Reactの再レンダリングをなるべく減らす - Aqutras Members' Blog
Reactコンポーネントの更新処理をキャンセルするためには、shouldComponentUpdate
内でfalse
を返してあげれば良い。(デフォルトではtrue
)
なので、子コンポーネントのprops
とstate
に変更がなければ、shouldComponentUpdate
内でfalse
を返す処理を実装すれば、データの更新がない子コンポーネントの更新を行わないようにできる。
props
とstate
が全て値型か、参照型を含むかで異なる実装を行う。
全て値型の場合
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通りの方法を使って実装しています。