この記事の目的は、「Reactが内部でどういう流れで差分を検知し、Actual DOMに変更をかけているのか」を理解して、メンタルモデルを作るのを助けること。
Virtual DOM(vDOM)について
JSXで書いたコンポーネント
// カウントするReactコンポーネント
function Counter() {
const [count, setCount] = useState(0)
return (
<main>
<div>
<h1>hello world!!</h1>
<div>クリック数: {count}</div>
<button onClick={() => setCount(count + 1)}>クリック</button>
</div>
</main>
)
}
JSXをcreateElementに置き換える
// JSXをcreateElementに置き換えると
function Counter() {
const [count, setCount] = useState(0)
return React.createElement(
'main',
null,
React.createElement(
'div',
null,
React.createElement('h1', null, 'hello world!!'),
React.createElement('div', null, 'クリック数: ', count),
React.createElement(
'button',
{ onClick: () => setCount(count + 1) },
'クリック'
)
)
)
}
// React.createElementの引数について
// ・first arg: HTML tag name.
// ・second arg: an object of properties.
// ・any additional args represent child elements.
//レンダリング時のVirtual Dom Treeはこんな感じ
// 1.初回
// main
// |- div
// |- h1
// | |- 'hello world!!'
// |- div
// | |- 'クリック数: 0'
// |- button
// | |- 'クリック'
// 2.ボタンを1回クリック→ 再レンダリングしてdiv要素を更新
// main
// |- div
// |- h1
// | |- 'hello world!!'
// |- div
// | |- 'クリック数: 1'
// |- button
// | |- 'クリック'
ボタンをクリックして変化があったのはdiv要素のみなので、div要素のみ再計算されてActual DOMの一部を更新する。つまり、button要素は更新されない「レンダーは時間を切り取ってスナップショットを取る」と公式に書かれているのは、Vurtial DOM Treeが上記の振る舞いをするからだと言える。
ブログサイトの記事一覧画像
Virtual DOM
Actual DOM
1.SearchBarからstateを更新
2.Virtual DOMの更新
3.差分検知(Fiber Reconcilation)
4.Actual DOMの一括更新
5.フィルタリング結果
Fluent React: Build Fast, Performant, and Intuitive Web Applications Node - Web API | MDN React Virtual DOM, Reconciliation and Fiber Reconciler state はスナップショットである