このテーマのゴール
ここでやりたいのは、「ボタンを押すと数字が増える」カウンターコンポーネントを通して、React の state とイベント処理の超基本を体で覚えることです。
画面に数字が表示されていて、
「増やす」ボタンを押すたびに 1, 2, 3… と増えていく。
この“ちっちゃい動き”の中に、React の大事な要素が全部詰まっています。
- 「今の値」を覚えておく state
- 「ボタンが押された」というイベント
- 「state が変わると画面が自動で更新される」という仕組み
これを一つずつ、ちゃんとつなげていきます。
まずは完成形のコードを見てみる
シンプルなカウンターコンポーネント
"use client";
import { useState } from "react";
export function Counter() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<div style={{ padding: "16px", border: "1px solid #e5e7eb", borderRadius: "8px" }}>
<p style={{ marginBottom: "8px" }}>現在のカウント: {count}</p>
<button
onClick={handleClick}
style={{
padding: "6px 12px",
borderRadius: "9999px",
border: "none",
backgroundColor: "#3b82f6",
color: "white",
cursor: "pointer",
}}
>
1 増やす
</button>
</div>
);
}
TSX// app/page.tsx
import { Counter } from "./Counter";
export default function Page() {
return (
<main style={{ padding: "24px", fontFamily: "system-ui, sans-serif" }}>
<h1 style={{ fontSize: "22px", marginBottom: "16px" }}>カウンターの例</h1>
<Counter />
</main>
);
}
TSX画面には「現在のカウント: 0」と表示され、
ボタンを押すたびに 1, 2, 3… と増えていきます。
useState で「今の値」を覚えておく
state とは「変わる値」を覚えておくための箱
この行が、今回の心臓部です。
const [count, setCount] = useState(0);
TSXここでやっていることを、かみ砕いて説明します。
countは「今のカウントの値」を表す変数setCountは「count を新しい値に更新するための関数」useState(0)は「初期値 0 で state を作る」という意味
イメージとしては、
「最初は count = 0 からスタートして、setCount(新しい値) を呼ぶたびに count が変わる。
そして、count が変わると React が自動で画面を描き直してくれる」
という感じです。
普通の変数(let count = 0 など)と違うのは、useState で作った値は、変わったときに画面も一緒に更新されるという点です。
JSX の中で state を表示する
この行も重要です。
<p>現在のカウント: {count}</p>
TSX{count} と書くことで、「今の count の値」を画面に埋め込んでいます。
- 最初は
count = 0なので「現在のカウント: 0」と表示される setCount(1)が呼ばれると、count = 1になり、「現在のカウント: 1」と表示が変わる
ここであなたがやっているのは「count を変えること」だけ。
「画面を更新する」処理は、全部 React が勝手にやってくれます。
ボタンが押されたときに count を増やす
onClick とイベントハンドラ
ボタンの部分を見てみましょう。
<button onClick={handleClick}>1 増やす</button>
TSXonClick={handleClick} は、
「このボタンがクリックされたら、handleClick という関数を実行してね」
という意味です。
その handleClick の中身がこれ。
function handleClick() {
setCount(count + 1);
}
TSXやっていることはシンプルで、
- 今の
countに 1 を足した値を setCountに渡している
だけです。
例えば、今 count = 3 なら、setCount(3 + 1) → setCount(4) が呼ばれ、
次のレンダリングでは count = 4 になり、画面には「現在のカウント: 4」と表示されます。
「ボタンを押す → state を変える → 画面が変わる」の流れ
このカウンターで起きていることを、流れで整理するとこうなります。
ユーザーがボタンをクリックするonClick に指定した handleClick が呼ばれるhandleClick の中で setCount(count + 1) が実行されるcount の値が変わる
React が「お、state 変わったな」と気づいて、コンポーネントをもう一度描画する
新しい count の値が画面に反映される
この「イベント → state 更新 → 再描画」という流れが、
React のインタラクティブな UI の基本パターンです。
もう一歩:初期値を props で変えられるようにする
「最初の値だけ変えたい」パターン
少しだけレベルを上げて、「カウンターの初期値を外から変えられるようにする」パターンも見てみましょう。
type CounterProps = {
initialValue?: number; // 省略可能
};
export function Counter({ initialValue = 0 }: CounterProps) {
const [count, setCount] = useState(initialValue);
function handleClick() {
setCount(count + 1);
}
return (
<div>
<p>現在のカウント: {count}</p>
<button onClick={handleClick}>1 増やす</button>
</div>
);
}
TSX使う側は、こう書けます。
<Counter /> // 0 からスタート
<Counter initialValue={5} /> // 5 からスタート
<Counter initialValue={10} /> // 10 からスタート
TSXここでのポイントは、
initialValueを props として受け取っている- 受け取らなかった場合は
= 0でデフォルト値を 0 にしている useState(initialValue)で「最初の count の値」を変えられるようにしている
というところです。
これで、「同じカウンターコンポーネントを、違う初期値で何度も使う」という再利用性が一気に上がります。
まとめ:このカウンターからつかんでほしいこと
この「ボタンを押すと増えるカウンターコンポーネント」で、絶対に持ち帰ってほしいのはこの感覚です。
useState は「変わる値」を覚えておくための箱で、[値, 更新関数] のペアを返してくれる
イベント(onClick)で「いつ state を変えるか」を決め、setCount で値を更新する
state が変わると、React が自動で画面を描き直してくれるので、自分で DOM をいじる必要はない
ここが腑に落ちると、
- いいねボタンのカウント
- カート内の商品数
- ステップ形式フォームの現在ステップ
みたいな「ユーザーの操作に応じて変わる UI」を、自信を持って書けるようになります。
もしよければ、このカウンターに「減らすボタン」や「リセットボタン」を足してみてください。setCount(count - 1) や setCount(0) をどう組み合わせるか考えるだけで、state とイベントの理解が一段深くなります。
