これまでReactの機能や描画を探ってきましたが、今日は違う視点から見ます。
計算機科学の基礎である
データ構造
です。
フロントエンドに必要なのかと感じるかもしれません。
しかし、私たちのコードやReactの内部では、効率のために多くの構造が使われています。
理論だけでなく、配列更新で不変性を守る理由や、状態管理と描画の仕組みを深く理解する助けになります。
Reactと関連する構造と、開発・内部での使い方を見ていきます。
Reactで最も頻繁に使う構造の一つです。
複数項目を表示する場合には欠かせません。
JavaScript配列のmapを使うのが一般的です。
各要素へ関数を実行し、結果の新しい配列を返します。
ReactはJSXなどを含むその配列を描画します。
import React from 'react';
interface Todo {
id: number;
text: string;
completed: boolean;
}
const initialTodos: Todo[] = [
{ id: 1, text: 'React 공부하기', completed: true },
{ id: 2, text: '자료구조 복습하기', completed: false },
{ id: 3, text: '블로그 글쓰기', completed: false },
];
function TodoList() {
const [todos, setTodos] = React.useState<Todo[]>(initialTodos);
return (
<ul>
{/* 배열의 map 함수를 사용하여 li 요소 배열 생성 */}
{todos.map(todo => (
// 각 항목에 고유한 key prop 전달이 필수!
<li key={todo.id} style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>
{todo.text}
</li>
))}
</ul>
);
}
参考:
Virtual DOMとFiberの描画原理・1日目
各要素へ一意で安定したkeyを渡すことが重要です。
1日目のReconciliationで学んだ
diffingアルゴリズム
は、keyから追加、削除、移動を効率よく認識します。
keyがない場合やindexを使う場合、途中の追加・削除を正しく追いづらく、不要なDOM操作で性能が落ちることがあります。
データ固有のIDを使うのが望ましい方法です。
状態更新では
Immutability
が重要です。
push、pop、spliceなどで直接変えず、map、filter、reduce、スプレッド演算子で新しい配列を返します。
Reactは
参照
の変更を浅く比較して、描画の必要性を判断する場合が多いからです。
直接変えると参照が同じで、検知されず再描画しない場合があります。
// ❌ 잘못된 예시: 원본 배열 직접 수정
newTodos.push({ id: 4, text: '새 할일', completed: false });
setTodos(newTodos); // React가 변화 감지 못할 수 있음
// ✅ 올바른 예시: 스프레드 연산자로 새 배열 생성
setTodos([...todos, { id: 4, text: '새 할일', completed: false }]);
// ✅ 올바른 예시: filter로 항목 삭제
setTodos(todos.filter(todo => todo.id !== idToRemove));
// ✅ 올바른 예시: map으로 특정 항목 업데이트
setTodos(todos.map(todo =>
todo.id === idToToggle ? { ...todo, completed: !todo.completed } : todo
));
配列と異なり、連続したメモリー配置は不要です。
各ノードが値と、次の要素への参照を持ってつながります。
開発で自作することは少なくても、
内部原理
の理解に重要です。
2日目のとおり、ReactはuseStateやuseEffectなどの状態管理に使います。
- Fiberは
Hookオブジェクト
のリストを、memoizedStateのポインターから保持する。
- 描画時は順にたどり、各フックの状態を返す。
- 順序が変わると別のHookを見るため、呼び出し順が常に同じでなければならない。

Hookオブジェクトの連結リスト
setStateやdispatchを呼ぶと、即座に変更せず、
Update
を
Update Queue
へ追加すると
2日目で学びました。
これも
単方向の連結リスト
です。
- 各Updateにはpayload、優先度、次のUpdateへのnextなどがある。
- 次のレンダーフェーズで順に処理し、最終状態を計算する。
- 順序どおりの処理と、途中への効率的な追加に適している。
Q:「Hooksはどう状態を管理しますか」「useStateの更新はどう処理しますか。」
A:FiberのHook連結リストやUpdate Queueの構造へ言及して説明します。
親子関係を持つノードからなる階層構造で、アプリと描画を理解するうえで欠かせません。
コードは入れ子の
コンポーネントツリー
を作ります。
Appからページ、レイアウト、各UIへ親子でつながり、画面構造を抽象的に表します。
ブラウザーはHTMLを解析し、メモリーに
DOMツリー
を作ります。
実際のページ構造を表し、各HTML要素がノードになります。
これを基にUIを描きます。
Reactは実DOMを直接操作する代わりに、
Virtual DOMツリー
をメモリーに保ちます。
JavaScriptオブジェクトなので軽く、速く操作できます。
状態変更時に新しいツリーを作り、前のものとdiffし、変更だけを実DOMへ効率よく反映します。
Reconciliationは、本質的には新旧二つのツリーの比較です。
ツリー走査
、主に*深さ優先探索(DFS)*に基づきます。
同じ階層を比べ、子を再帰的に探索して変更を見つけます。
keyは兄弟同士の比較効率に重要です。
頂点と辺からなる構造で、複雑な関係や依存を表します。
React周辺でも多くの使い方があります。
モジュールの依存
WebpackやViteはimport・exportの関係から依存グラフ
を作ります。
分析して必要なコードだけをまとめ、最適化します。
フックの依存
useEffect、useMemo、useCallbackの配列は、状態やpropsへの依存を示します。
Reactは変更時だけコールバックを再実行したり、計算し直したりします。
概念的にはこれも依存関係です。
src/
├── App.js - Header, Footer, Home 참조
├── components/
│ ├── Header.js - Nav 참조
│ ├── Footer.js - Button 참조
│ ├── Nav.js
│ └── Button.js
├── pages/
└ └── Home.js - Button 참조
의존성 그래프 예시 App.js
/ | \
Header Footer pages
| | |
Nav Button - Home
React.lazyで分割すると、バンドラーは小さな
chunk
を作ります。
ページのchunkが共通ライブラリへ依存するなど、間にも関係があります。
その依存をグラフで管理し、ページに必要なものをまとめて読み込みます。
キーをハッシュ値へ変え、それをインデックスにして値を保存・検索する構造です。
平均的に、検索・挿入・削除をO(1)で行えるのが特徴です。
JavaScriptではMapや通常のObjectで、似た機能を使えます。
React QueryやSWRは、要求結果のキャッシュへ類似構造を使います。
- 一意の
Query Key
をハッシュキーのようにして、データを保存する。
- 同じキーなら通信せず、平均O(1)でキャッシュから返す。
ReactのMemoizationにも、ハッシュテーブルやMapに似た構造を使います。
計算済みの結果を保存し、同じ入力なら計算を省いて返す技術です。
- React.memo、useMemo、useCallbackは、propsや依存値をキーとして、コンポーネント・値・関数を保つ。
- 次の描画で入力が同じなら、保存結果を返して計算や描画を省く。
- 内部の保存場所がハッシュテーブルやMapに似た働きをして、速い検索を実現する。
配列、連結リスト、ツリー、グラフ、ハッシュテーブルを確認しました。
配列
は一覧表示の基本。不変性とkeyが重要。
連結リスト
はHooksとUpdate Queueの基盤。
ツリー
はコンポーネント、DOM、Virtual DOMを表し、再調整に関係する。
グラフ
はモジュールやchunkなどの複雑な依存を示す。
ハッシュテーブル・Map
は、高速な検索でキャッシュやメモ化を支える。
アルゴリズム問題を解くためだけでなく、Reactの効率的な動作や、自分のコードが性能へ与える影響を深く理解する助けになります。
次回は
良いコンポーネントの設計原則とパターン
を学びます。
動くだけでなく、再利用、テスト、保守のしやすい構造を一緒に考えます。
- データ構造の教材は、特定サイトより一般的なキーワードを案内するほうがよい場合があります。
- JavaScriptのデータ構造・アルゴリズムの講座や書籍。例:『JavaScriptで学ぶデータ構造とアルゴリズム』。
- React公式ドキュメントの内部動作関連の節。