useState - 状態管理の基礎
Reactで、「変化する値」を扱うには、useStateを使います。
状態(State)とは?
状態とは、「時間とともに変化する値」のことです。
例:
- カウンター(クリックするたびに増える数値)
- 入力フォームの値
- モーダルの開閉状態
- チェックボックスのON/OFF
なぜuseStateが必要?
通常の変数では、Reactは再レンダリングしてくれません。
❌ 通常の変数(動かない)
function Counter() {
let count = 0; // 通常の変数
const increment = () => {
count = count + 1;
console.log(count); // コンソールには表示されるが...
};
return (
<div>
<p>カウント: {count}</p> {/* 画面は更新されない! */}
<button onClick={increment}>増やす</button>
</div>
);
}✅ useState(動く!)
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0); // useState を使う
const increment = () => {
setCount(count + 1); // setCount で更新
};
return (
<div>
<p>カウント: {count}</p> {/* 画面が更新される! */}
<button onClick={increment}>増やす</button>
</div>
);
}useStateの基本
書き方
const [状態変数, 更新関数] = useState(初期値);- 状態変数: 現在の値を格納
- 更新関数: 値を更新するための関数
- 初期値: 最初の値
具体例
import { useState } from 'react';
function Example() {
// countという状態を作る、初期値は0
const [count, setCount] = useState(0);
return (
<div>
<p>現在の値: {count}</p>
<button onClick={() => setCount(count + 1)}>
増やす
</button>
</div>
);
}useStateの戻り値はタプル型
useStateの戻り値は、タプル型です。
// useStateの戻り値
const result = useState(0);
// result の型: [number, (value: number) => void]
// 分割代入で取り出す
const [count, setCount] = result;
// count: number
// setCount: (value: number) => voidタプル型とは?
タプル型は、要素数と各要素の型が決まっている配列です。
- 1番目の要素: 現在の状態値
- 2番目の要素: 状態を更新する関数
// useStateは必ず2つの要素を返す
const [count, setCount] = useState(0);
// ↑ ↑
// 状態値 更新関数
// 複数のuseStateでも同じ
const [name, setName] = useState("");
const [isOpen, setIsOpen] = useState(false);なぜタプル型を使うのか?
タプル型のおかげで、好きな名前をつけられます。
// もしオブジェクトだったら...
const { value, setValue } = useState(0); // 名前が固定される
// タプルだから...
const [count, setCount] = useState(0); // 好きな名前!
const [score, setScore] = useState(0); // これも!
const [total, setTotal] = useState(0); // 何度でも使える!💡 タプル型について詳しく学ぶ: 第2章「TypeScript基礎 - タプル型」でタプル型の基礎を学べます。
いろいろな型の状態
数値の状態
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>カウント: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
<button onClick={() => setCount(count - 1)}>-1</button>
<button onClick={() => setCount(0)}>リセット</button>
</div>
);
}文字列の状態
function NameInput() {
const [name, setName] = useState("");
return (
<div>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="名前を入力"
/>
<p>こんにちは、{name}さん!</p>
</div>
);
}真偽値の状態
function ToggleButton() {
const [isOn, setIsOn] = useState(false);
return (
<div>
<p>状態: {isOn ? "ON" : "OFF"}</p>
<button onClick={() => setIsOn(!isOn)}>
切り替え
</button>
</div>
);
}複数のuseStateを使う
1つのコンポーネントで、複数の状態を管理できます。
function LoginForm() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [rememberMe, setRememberMe] = useState(false);
const handleSubmit = () => {
console.log({ email, password, rememberMe });
};
return (
<div>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="メールアドレス"
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="パスワード"
/>
<label>
<input
type="checkbox"
checked={rememberMe}
onChange={(e) => setRememberMe(e.target.checked)}
/>
ログイン状態を保持
</label>
<button onClick={handleSubmit}>ログイン</button>
</div>
);
}ポイント:
- それぞれの状態に別々のuseStateを使う
- 関連する値でも、基本的には別々の状態にする
- 必要なだけuseStateを使ってOK
よくある間違い
❌ 直接値を代入しない
const [count, setCount] = useState(0);
// ❌ ダメな例
count = 5; // 直接代入してはダメ!
// ✅ 正しい例
setCount(5); // 更新関数を使う❌ 条件によって異なる数のuseStateを呼ばない
// ❌ ダメな例
function Example() {
const [count, setCount] = useState(0);
if (count > 10) {
const [message, setMessage] = useState(""); // 条件内でuseState
}
return <div>...</div>;
}
// ✅ 正しい例
function Example() {
const [count, setCount] = useState(0);
const [message, setMessage] = useState(""); // 常に同じ順番で
return <div>...</div>;
}理由: Reactは、useStateを呼ばれた順番で状態を管理しています。条件によって順番が変わると、正しく動作しません。
実践例:シンプルなカウンターアプリ
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div style={{ textAlign: 'center', padding: '20px' }}>
<h1>カウンター</h1>
<p style={{ fontSize: '48px', fontWeight: 'bold' }}>
{count}
</p>
<div style={{ display: 'flex', gap: '10px', justifyContent: 'center' }}>
<button onClick={() => setCount(count - 1)}>-1</button>
<button onClick={() => setCount(0)}>リセット</button>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
</div>
);
}
export default Counter;もっと学びたい人へ
useStateには、この章で紹介した以外にも、いくつかの使い方があります。
まとめ
useStateの基本
- useState: 状態(変化する値)を管理するHook
- 書き方:
const [状態, 更新関数] = useState(初期値) - 更新方法: 更新関数を使う(直接代入しない)
状態の型
- 数値: カウンターなど
- 文字列: 入力フォームの値など
- 真偽値: ON/OFF、開閉状態など
ルール
- 複数のuseStateを使える
- useStateは常に同じ順番で呼ぶ
- 状態は直接変更せず、更新関数を使う
次は、副作用を扱うuseEffectを学びましょう!