リファクタリング
パフォーマンス
React
redux

React Redux の 過剰なコンポーネントアップデートを抑制する方法一覧

React Reduxで作業をしていると、過剰にコンポーネントがアップデートされるシーンがでてくるかもしれません。

アップデート抑制方法は色々ありますが、違いが分かりにくかったため
今回は比較リストを作成しました。

関連:React Redux の 高負荷なコンポーネントを高速で突き止める

コンポーネントのアップデート抑制方法一覧

※ React Reduxのみで実装可能な抑制方法一覧です。

class component で制御する場合

名前 比較方法 概要
pure component *shallow equal Propsに変更がなければ component をアップデートしない
shouldComponentUpdate 手動設定 shouldComponentUpdate関数で、返り値が false の場合 component をアップデートしない

container component で制御する場合

名前 比較方法 概要
areStatesEqual strictly equal Stateに変更がなければ対象のpresentational コンポーネント を呼ばない
areOwnPropsEqual *shallow equal mapStateToProps と dispatchStateToProps と mergeProps 以外 に渡される Propsに変更がなければ対象の presentational component を呼ばない
areStatePropsEqual *shallow equal mapStateToPropsで渡される値に変更がなければ対象の presentational component を呼ばない
areMergedPropsEqual *shallow equal mergePropsで渡される値に変更がなければ対象の presentational component を呼ばない
*shallow equal について

2つのオブジェクトのキーを1つづつ処理し、値を比較していきます。
値が object, function だった場合は厳密な比較ができず、常に違うものと認識されるため注意

アップデート抑制方法

pure component

特徴

  • class component で使用可能
  • 渡される全てのPropsを比較
  • 全てのPropsを比較する上、shallow equal のため function, objectがPropsに入ってないことが前提となる
  • シンプル

記述例

export class HogeComponent extends React.PureComponent {
    // contents
}

shouldComponentUpdate

特徴

  • 比較する項目を自分で設定できる
  • class component で使用可能

記述例

export class HogeComponent extends React.Component {
    public shouldComponentUpdate(nextProps, nextState) {
        return (
          this.props.name !== nextProps.name ||
          this.state.number !== nextState.number
        )
    }
    // contents
}

areStatesEqual

特徴

  • Stateをまるごと比較できる
  • connect関数の第4引数のoptionで設定
  • container component で使用される
  • object の比較が可能

記述例

connect(
  mapStateToProps,
  mapDispatchToProps,
  null,
  {
    areStatesEqual(next, prev) {
      return next.state === prev.state
    }
  }
)(HogeComponent)

areOwnPropsEqual

特徴

  • mapStateToPropsとmapDispatchToPropsとmergeProps 以外 に渡す値を比較
  • connect関数の第4引数のoptionで設定
  • container component で使用される
  • 比較内容にfunction, object がある場合はそれらを避けるように比較する必要がある

記述例

connect(
  mapStateToProps,
  mapDispatchToProps,
  null,
  {
    areOwnPropsEqual(next, prev) {
      return next === prev
    }
  }
)(HogeComponent)

areStatePropsEqual

特徴

  • mapStateToPropsの値を比較
  • connect関数の第4引数のoptionで設定
  • container component で主に使用
  • shallow equal なので function, object がある場合はそれらを避けるように比較する必要がある

記述例

connect(
  mapStateToProps,
  mapDispatchToProps,
  null,
  {
    areStatePropsEqual(next, prev) {
      return next === prev
    }
  }
)(HogeComponent)

areMergedPropsEqual

特徴

  • mergePropsで渡している値を比較
  • connect関数の第4引数のoptionで設定
  • container component で主に使用
  • shallow equal なので function, object がある場合はそれらを避けるように比較する必要がある

記述例

connect(
  state => state,
  dispatch => ({ dispatch }),
  mergeProps,
  {
    areMergedPropsEqual(next, prev) {
      return next === prev
    }
  }
)(HogeComponent)

あとがき

プラグインに頼らないアップデート抑制方法としてこちらを挙げました。

ご指摘箇所あればすぐ直しますのでコメントくださいませ。

最後までお読み頂きありがとうございました。