はじめに
Reactは、Meta(旧Facebook)が開発したJavaScriptライブラリです。
Webアプリケーションのユーザーインターフェース(UI)を構築するために広く使われており、世界中の多くの企業やプロダクトで採用されています。
この記事では、カウンターアプリを題材にしながら、Reactの基本的な考え方と使い方を丁寧に解説します。
1. Reactとは
ReactはUIをコンポーネントという小さな部品に分割して組み立てる考え方が特徴です。
レゴブロックのように、小さな部品を組み合わせて大きなアプリケーションを作ります。
Reactの主な特徴
| 特徴 | 説明 |
|---|---|
| コンポーネント指向 | UIを再利用可能な部品に分割できます |
| 仮想DOM | 差分だけを効率よく更新するため高速です |
| 宣言的UI | 「どう見えるか」を記述するだけで、DOMの操作はReactが担当します |
| 豊富なエコシステム | ライブラリやツールが充実しています |
2. 環境セットアップ
まず、Node.jsがインストールされていることを確認してください。
ターミナルで以下のコマンドを実行して、バージョンが表示されれば準備完了です。
node -v
プロジェクトの作成
Viteを使ってReactプロジェクトを作成します。
Viteは高速なビルドツールで、React開発に広く使われています。
npm create vite@latest my-counter-app -- --template react
cd my-counter-app
npm install
npm run dev
ブラウザで http://localhost:5173 を開くと、Reactアプリが起動しています。
3. プロジェクト構成を理解する
作成されたプロジェクトのフォルダ構成を確認してみましょう。
my-counter-app/
├── public/ # 静的ファイル(画像など)
├── src/
│ ├── App.jsx # メインのコンポーネント
│ ├── main.jsx # エントリーポイント(起動口)
│ └── index.css # グローバルスタイル
├── index.html # HTMLテンプレート
└── package.json # 依存関係の管理ファイル
最初に注目するのは src/App.jsx です。
このファイルがアプリケーションの中心となるコンポーネントです。
4. コンポーネントとは
Reactでは、画面の各部分をコンポーネントという単位で管理します。
コンポーネントは、JavaScriptの関数として書くのが現在の主流です。
function Greeting() {
return <h1>こんにちは、React!</h1>;
}
コンポーネントは以下のルールに従います。
- 関数名は大文字で始める(例:
MyButton、Counter) - JSX(HTMLのような記法)を
returnで返す - 1つのルート要素を返す必要がある
5. JSXを理解する
JSXは、JavaScriptの中にHTMLのような記法を書けるReact独自の構文です。
見た目はHTMLに似ていますが、いくつか異なるルールがあります。
HTMLとJSXの違い
// HTML
<div class="container">
<label for="input">名前</label>
</div>
// JSX(classはclassName、forはhtmlForに変わります)
<div className="container">
<label htmlFor="input">名前</label>
</div>
JavaScriptの式を埋め込む
JSXの中では {} を使ってJavaScriptの式を埋め込むことができます。
function Greeting() {
const name = "React";
const year = new Date().getFullYear();
return (
<div>
<h1>こんにちは、{name}!</h1>
<p>現在の年:{year}年</p>
</div>
);
}
6. はじめてのカウンター:propsを使う
props(プロパティの略)は、親コンポーネントから子コンポーネントへデータを渡す仕組みです。
HTML属性のように書くことができます。
表示専用のカウンターコンポーネント
まずはカウントの数値を表示するだけのシンプルなコンポーネントを作ってみましょう。
// CountDisplay.jsx(表示専用コンポーネント)
function CountDisplay({ count }) {
return <p className="count">{count}</p>;
}
// App.jsx(使う側)
function App() {
return (
<div>
<CountDisplay count={42} />
</div>
);
}
count={42} のように属性として渡した値が、子コンポーネントの引数 { count } で受け取れます。
propsの特徴
// 複数のpropsを渡すこともできます
function CountDisplay({ count, label, color }) {
return (
<p style={{ color: color }}>
{label}:{count}
</p>
);
}
// 使う側
<CountDisplay count={10} label="現在のカウント" color="green" />
注意: propsは読み取り専用です。子コンポーネントの中でpropsの値を書き換えることはできません。
7. stateで動きをつける
propsは親から受け取るデータでしたが、state(ステート)はコンポーネント自身が持つデータです。
stateが変わると、Reactは自動的に画面を再描画します。
useState というReactの機能(フック)を使って、stateを管理します。
import { useState } from "react";
function Counter() {
// [現在の値, 値を更新する関数] = useState(初期値)
const [count, setCount] = useState(0);
return (
<div>
<p>カウント:{count}</p>
</div>
);
}
stateの更新ルール
stateを変更するには、必ず set〇〇 関数(セッター)を使います。
直接 count = 1 のように書き換えてはいけません。
// ✅ 正しい書き方
setCount(10);
setCount(count + 1); // 現在の値に1を足す
// ❌ 間違った書き方(Reactが変更を検知できません)
count = 10;
count++;
8. イベントハンドラーを使う
ボタンのクリックなどのユーザー操作に応答するには、イベントハンドラーを使います。
JSXでは onClick のような属性にハンドラー関数を渡します。
function Counter() {
const [count, setCount] = useState(0);
// ハンドラー関数を定義
function handleClick() {
setCount(count + 1);
}
return (
<div>
<p>カウント:{count}</p>
{/* onClick に関数を渡す(呼び出しではなく参照を渡す点に注意) */}
<button onClick={handleClick}>増やす</button>
</div>
);
}
よくある間違い
// ✅ 正しい:関数の参照を渡す
<button onClick={handleClick}>クリック</button>
// ❌ 間違い:即座に実行されてしまう(レンダリング時に呼ばれる)
<button onClick={handleClick()}>クリック</button>
// ✅ 引数を渡したい場合はアロー関数でラップする
<button onClick={() => handleClick(5)}>5増やす</button>
9. カウンターを完成させる
ここまで学んだことを組み合わせて、実用的なカウンターアプリを完成させましょう。
以下の機能を実装します。
- カウントの増加・減少
- リセット
- カウントが正のとき緑、負のとき赤で表示
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
function increment() {
setCount(count + 1);
}
function decrement() {
setCount(count - 1);
}
function reset() {
setCount(0);
}
// カウントの値によって色を切り替える
function getColor() {
if (count > 0) return "green";
if (count < 0) return "red";
return "black";
}
return (
<div style={{ textAlign: "center", padding: "2rem" }}>
<h1>カウンター</h1>
{/* カウントの表示 */}
<p style={{ fontSize: "4rem", color: getColor() }}>{count}</p>
{/* ボタン群 */}
<div style={{ display: "flex", gap: "1rem", justifyContent: "center" }}>
<button onClick={decrement}>−</button>
<button onClick={reset}>リセット</button>
<button onClick={increment}>+</button>
</div>
</div>
);
}
export default Counter;
条件付きレンダリング
count の値に応じてメッセージを表示する場合は、条件付きレンダリングが便利です。
return (
<div>
<p style={{ fontSize: "4rem", color: getColor() }}>{count}</p>
{/* && を使った条件付き表示 */}
{count === 0 && <p>ゼロです</p>}
{/* 三項演算子を使った切り替え */}
<p>{count >= 0 ? "プラスです" : "マイナスです"}</p>
</div>
);
10. コンポーネントを分割する
アプリが大きくなってきたら、コンポーネントを分割して整理しましょう。
分割することで再利用しやすく、テストもしやすくなります。
ファイル構成
src/
├── components/
│ ├── CountDisplay.jsx # 数値の表示
│ └── CountButtons.jsx # ボタン群
├── App.jsx
└── main.jsx
CountDisplay.jsx
// src/components/CountDisplay.jsx
function CountDisplay({ count }) {
function getColor() {
if (count > 0) return "green";
if (count < 0) return "red";
return "black";
}
return (
<p style={{ fontSize: "4rem", color: getColor() }}>
{count}
</p>
);
}
export default CountDisplay;
CountButtons.jsx
// src/components/CountButtons.jsx
function CountButtons({ onIncrement, onDecrement, onReset }) {
return (
<div style={{ display: "flex", gap: "1rem", justifyContent: "center" }}>
<button onClick={onDecrement}>−</button>
<button onClick={onReset}>リセット</button>
<button onClick={onIncrement}>+</button>
</div>
);
}
export default CountButtons;
App.jsx(統合)
// src/App.jsx
import { useState } from "react";
import CountDisplay from "./components/CountDisplay";
import CountButtons from "./components/CountButtons";
function App() {
const [count, setCount] = useState(0);
return (
<div style={{ textAlign: "center", padding: "2rem" }}>
<h1>カウンター</h1>
<CountDisplay count={count} />
<CountButtons
onIncrement={() => setCount(count + 1)}
onDecrement={() => setCount(count - 1)}
onReset={() => setCount(0)}
/>
</div>
);
}
export default App;
ポイント: stateは「それを必要とする最上位のコンポーネント」に置きます。
今回はAppがカウントを管理し、子コンポーネントにはpropsで渡しています。
これをステートのリフトアップと呼びます。
11. まとめ
この記事で学んだReactの基本をおさらいしましょう。
| 概念 | 役割 | 例 |
|---|---|---|
| コンポーネント | UIの部品 | function Counter() { ... } |
| JSX | UIの見た目を記述する構文 | <p>{count}</p> |
| props | 親→子へのデータの受け渡し | <Counter initialCount={0} /> |
| state | コンポーネント自身が持つデータ | const [count, setCount] = useState(0) |
| イベントハンドラー | ユーザー操作への応答 | <button onClick={handleClick}> |
次のステップ
Reactの基礎を理解したら、以下のトピックに進んでみましょう。
-
useEffect— データ取得や副作用の処理 - React Router — ページ遷移の実装
- Context API — コンポーネント間でのデータ共有
- TypeScript — 型安全なReact開発
- Next.js — React製のフルスタックフレームワーク
参考リンク
この記事がReact学習の第一歩になれば幸いです。