React で前回と同一の React Node は re-render されない仮説
Published: 2023/10/14
例えば React.memo の公式資料 にて、以下の記述がある。
In practice, you can make a lot of memoization unnecessary by following a few principles:
- When a component visually wraps other components, let it accept JSX as children. This way, when the wrapper component updates its own state, React knows that its children don’t need to re-render.
どういうことかというと、 children を(直)描写する系の、ラッパー的なコンポーネントを記述したとき、ラッパー側の state が変更されただけならば、 children は re-render されない、ということ。
React components - when do children re-render?
Learn when child components in React re-render and how to structure a React apps with both performance and simplicity in mind.
whereisthemouse.com

具体的にその振舞いについて検証を行ったコードの例などは、上記の記事などから参照できる。
Object.is
的に等価であれば、その先を re-render しない
仮説: reconciliation では、 上記の re-render 抑制の機構があるとして、シンプルで分かりやすい仮説は、 reconciliation の際に前回と今回の React Node を、 React がフレームワーク的に採用している等価性判定ロジックである、 Object.is
でもって比較し、もしそれが真であるならば、その先の re-render を行わない、という振舞いをしていること、になる。
ラッパーコンポーネントと内部コンポーネントの JSX を記述した、それらの親コンポーネントの render の時点で、ラッパーに対する children 式は確定し、ラッパーが状態変化等により re-render する際であっても、親の re-render さえ起きていなければ、そこに渡る children
の prop は不変であることが期待できる。
普通の React Component の記述において、親が re-render すると子も re-render していくのは、親が render した際に生成される React Node はオブジェクトなので、基本的に前回の render の結果とは、 Object.is
的には等価でないため、そのまま子コンポーネントの re-render が走っていく、のだと解釈できる。
そのような機構が動いている中で、きちんと React Element の type
と 各 props
の中身を等価性比較して、変わっていなければ re-render を抑制する機構として、 React.memo
は用意されているのだ、と理解される。
Tags: react
関連記事
(メモ) React における children
2023/8/18
React における配列の reconciliation に関する検証と考察
2023/8/15