React核心思想と誕生背景 - nyg1971/vanillaVsReact GitHub Wiki
2010年代初頭、Facebook(現Meta)は深刻な問題を抱えていました:
// 従来のjQuery時代の課題例
$('#notification-count').text(newCount);
$('#sidebar-notifications').html(notificationHTML);
$('#header-bell').addClass('has-notifications');
// 状態が分散し、整合性を保つのが困難
- 状態管理の複雑化: データが変更されると、複数のDOM要素を手動で更新
- バグの温床: 更新漏れや不整合が頻発
- スケーラビリティの限界: 機能が増えるほど管理が困難
- 依存関係の管理: 一つの変更が複数箇所に影響
- テストの困難さ: DOM操作が複雑で単体テストが書きにくい
Reactは根本的に異なるアプローチを提案しました:
「データが変わったら、画面全体を再描画すればいい」
// React的思考
function App({ notifications }) {
return (
<div>
<Header notificationCount={notifications.length} />
<Sidebar notifications={notifications} />
<MainContent />
</div>
);
}
// データ(notifications)が変わると、自動的に全体が再計算される
従来(命令的):
// 「どうやって」変更するかを記述
if (isLoggedIn) {
loginButton.style.display = 'none';
userMenu.style.display = 'block';
userMenu.textContent = userName;
}
React(宣言的):
// 「何を」表示するかを記述
function Header({ isLoggedIn, userName }) {
return (
<div>
{isLoggedIn ? (
<UserMenu userName={userName} />
) : (
<LoginButton />
)}
</div>
);
}
宣言的UIの利点:
- コードが読みやすい
- バグが入りにくい
- テストしやすい
- 予測可能な動作
UIを独立した部品(コンポーネント)として構築:
// 再利用可能な部品として設計
function Button({ onClick, children, variant = 'primary' }) {
return (
<button
className={`btn btn-${variant}`}
onClick={onClick}
>
{children}
</button>
);
}
// 様々な場所で再利用
<Button onClick={handleSave}>保存</Button>
<Button onClick={handleCancel} variant="secondary">キャンセル</Button>
コンポーネント指向の利点:
- 再利用性が高い
- 保守性が向上
- チーム開発での分業がしやすい
- 単体テストが書きやすい
データは常に上から下へ流れる:
function App() {
const [todos, setTodos] = useState([]);
return (
<div>
{/* データが上から下へ流れる */}
<TodoForm onAdd={(todo) => setTodos([...todos, todo])} />
<TodoList todos={todos} onToggle={handleToggle} />
</div>
);
}
単一データフローの利点:
- データの流れが追いやすい
- デバッグしやすい
- 予期しない副作用が起きにくい
- 状態管理が明確
Reactは関数型プログラミングの概念を多く取り入れています:
- 純粋関数: 同じ入力に対して同じ出力
- 不変性: データを直接変更せず、新しいデータを作成
- 合成: 小さな関数を組み合わせて複雑な機能を実現
// 純粋関数としてのコンポーネント
function UserCard({ user }) {
// 同じuserを渡すと常に同じ結果
return (
<div>
<h3>{user.name}</h3>
<p>{user.email}</p>
</div>
);
}
項目 | 従来のアプローチ | React |
---|---|---|
UI更新 | 手動でDOM操作 | 自動再描画 |
状態管理 | 分散管理 | 集中管理 |
コード | 命令的 | 宣言的 |
再利用性 | 低い | 高い |
テスト | 困難 | 容易 |
デバッグ | 困難 | 容易 |
- 「DOMを操作する」から「データを管理する」への転換
- UIをデータの関数として捉える発想
- エラーが起きにくい設計
- デバッグツールの充実
- ホットリロードによる高速開発
- 大規模アプリケーションでも破綻しない設計
- チーム開発での一貫性
- 状態管理: Redux, Zustand, Recoil
- ルーティング: React Router
- スタイリング: styled-components, CSS-in-JS
- 開発ツール: Create React App, Next.js
- Vue.js: 似たようなコンポーネント指向
- Angular: Reactの思想を取り入れた設計変更
- Svelte: さらなる最適化を追求
Reactの核心は**「複雑さの管理」**にあります:
- 複雑なUI状態をシンプルなデータとして表現
- 複雑なDOM操作を宣言的な記述に置き換え
- 複雑な依存関係を単一方向のデータフローで整理
この思想により、開発者はビジネスロジックに集中でき、保守性の高いアプリケーションを構築できるようになりました。