Skip to content

なぜReactか

Reactは、Meta(旧Facebook)が開発した、**フルスタックなWebアプリケーションを構築するための基盤(アーキテクチャ)**です。Next.js(Server Components)が標準となった現在、Reactを単なる「JavaScriptライブラリ」と呼ぶのは不正確です。

1. 宣言的UIプログラミングモデル

Section titled “1. 宣言的UIプログラミングモデル”

Reactの真の強みは、**「UIをデータ(状態)の投影として扱えるプログラミングモデル(宣言的UI)」**にあります。

// 命令的なコード(問題)
function updateUI() {
const element = document.getElementById('counter');
element.textContent = count;
if (count > 10) {
element.style.color = 'red';
}
}
// 宣言的なコード(React)
function Counter({ count }) {
return (
<div style={{ color: count > 10 ? 'red' : 'black' }}>
{count}
</div>
);
}

重要なポイント: UIの見た目がデータ(状態)から自動的に導出されるため、状態管理が明確で、バグが起きにくいコードを書けます。

2. 仮想DOMについて(誤解の修正)

Section titled “2. 仮想DOMについて(誤解の修正)”

❌ 古い説明: 「Reactは仮想DOMを使うから速い」

✅ 現在の正解:

  • 仮想DOMそのものが速いわけではありません。SvelteやSolidJSなど「仮想DOMを使わない(No VDOM)」ライブラリの方が高速なケースも多いです。
  • Reactの強みは仮想DOMそのものではなく、宣言的UIプログラミングモデルと、それを支える圧倒的なエコシステムにあります。
// コンポーネントの定義
function Button({ label, onClick }) {
return <button onClick={onClick}>{label}</button>;
}
// コンポーネントの組み合わせ
function App() {
return (
<div>
<Button label="Click me" onClick={() => alert('Clicked!')} />
</div>
);
}

注意: 単に「ボタンを共通化できる」程度の再利用性は、今やどのフレームワークでも当たり前です。これはReactの特徴ではありません。

Reactの真の強みは、**「ロジック(Hooks)の再利用性」**にあります。

// カスタムHook: ロジックの再利用
function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue);
const increment = () => setCount(c => c + 1);
const decrement = () => setCount(c => c - 1);
return { count, increment, decrement };
}
// 複数のコンポーネントで同じロジックを再利用
function Counter1() {
const { count, increment } = useCounter();
return <button onClick={increment}>Count: {count}</button>;
}
function Counter2() {
const { count, increment } = useCounter(10);
return <div onClick={increment}>Value: {count}</div>;
}

2. マルチプラットフォームへの展開力

Section titled “2. マルチプラットフォームへの展開力”

Reactのもう一つの強みは、**「マルチプラットフォーム(Web、モバイルのReact Native、VR等)への展開力」**にあります。

  • Web: React(Next.js、Remix等)
  • モバイル: React Native
  • デスクトップ: Electron
  • VR/AR: React 360、React Three Fiber
  • CLI: Ink

同じプログラミングモデルで、複数のプラットフォームに対応できることがReactの大きな強みです。

Reactには、豊富なライブラリとツールが存在します:

  • 状態管理: Redux、Zustand、Jotai、Recoil
  • データフェッチング: React Query、SWR、Apollo Client
  • フォーム: React Hook Form、Formik
  • ルーティング: React Router、Next.js Router
  • UIライブラリ: Material-UI、Chakra UI、Ant Design
  • ビルドツール: Vite、Webpack、Turbopack

4. フルスタックなWebアプリケーション構築の基盤

Section titled “4. フルスタックなWebアプリケーション構築の基盤”

Next.js(Server Components)が標準となった現在、Reactは**「フルスタックなWebアプリケーションを構築するための基盤(アーキテクチャ)」**へと進化しました。

  • Server Components: サーバーサイドでのレンダリング
  • Server Actions: サーバーサイドでのロジック実行
  • ストリーミング: インクリメンタルなHTMLストリーミング
  • React Compiler (React Forget): 開発者がuseMemouseCallbackを書かなくても、Reactが自動でパフォーマンスを最適化(現在進行形の潮流)

React Compiler(通称React Forget)は、開発者がuseMemouseCallbackを書かなくても、Reactが自動でパフォーマンスを最適化してくれる技術です。

従来のアプローチ:

// 開発者が手動でメモ化
const expensiveValue = useMemo(() => {
return computeExpensiveValue(data);
}, [data]);
const handleClick = useCallback(() => {
// 処理
}, []);

React Compilerのアプローチ:

// React Compilerが自動で最適化
const expensiveValue = computeExpensiveValue(data);
const handleClick = () => {
// 処理
};

React Compilerが自動的に、どこでメモ化が必要かを判断し、最適化を実行します。これにより、開発者はビジネスロジックに集中できるようになります。

React Compilerが最適化を行う際、propsは不変(immutable)として扱われます。これは、React Compilerが安全に最適化を行うための重要な前提条件です。

❌ 問題のあるコード(React Compiler使用時):

function UserCard({ user }) {
// ❌ エラー: propsはreadOnlyなので、直接変更できない
user.name = 'New Name'; // これは動作しない(またはエラー)
user.items.push('new item'); // これも動作しない
return <div>{user.name}</div>;
}

✅ 正しいコード:

function UserCard({ user }) {
// ✅ propsを読み取るだけ(推奨)
return <div>{user.name}</div>;
}
// または、新しいオブジェクトを作成する
function UserCard({ user }) {
const updatedUser = {
...user,
name: 'New Name'
};
return <div>{updatedUser.name}</div>;
}

重要なポイント:

  1. Propsは読み取り専用: React Compiler使用時、propsは不変として扱われます
  2. 状態の変更はuseStateを使用: コンポーネント内で状態を変更したい場合は、useStateを使用します
  3. イミュータブルな操作: オブジェクトや配列を変更する場合は、新しいオブジェクト/配列を作成します
function UserList({ users }) {
const [localUsers, setLocalUsers] = useState(users);
const addUser = () => {
// ✅ 新しい配列を作成(イミュータブルな操作)
setLocalUsers([...localUsers, { id: 1, name: 'New User' }]);
};
return (
<div>
{localUsers.map(user => <div key={user.id}>{user.name}</div>)}
<button onClick={addUser}>Add User</button>
</div>
);
}

この制約により、React Compilerは安全に最適化を行い、予期しない副作用を防ぐことができます。

  1. 宣言的UIプログラミングモデル: UIをデータ(状態)の投影として扱える
  2. ロジック(Hooks)の再利用性: 複数のコンポーネントでロジックを共有
  3. マルチプラットフォーム対応: Web、モバイル、デスクトップ、VR等に対応
  4. 圧倒的なエコシステム: 豊富なライブラリとツール
  5. フルスタックなWebアプリケーション構築: Server Components、Server Actions等によるサーバーサイド機能
  6. 自動最適化(React Compiler): 将来的には、手動でのメモ化が不要に