React useStateの使い方
コンポーネントの状態管理入門
useStateはReactで最も基本的なHookで、コンポーネントに「状態(state)」を持たせることができます。
この記事では、useStateの基本から実践的なパターンまで解説します。
こんな人向けの記事です
- React Hooksの基本を学びたい
- useStateの使い方を知りたい
- フォームやカウンターなどの状態管理を実装したい
Step 1useStateの基本
React(JSX)
import { useState } from 'react';
function Counter() {
// [現在の値, 更新関数] = useState(初期値)
const [count, setCount] = useState(0);
return (
<div>
<p>カウント: {count}</p>
<button onClick={() => setCount(count + 1)}>
+1
</button>
</div>
);
}
| 要素 | 役割 |
|---|---|
count | 現在の状態の値(読み取り専用) |
setCount | 状態を更新する関数 |
useState(0) | 初期値を0に設定 |
状態が変わるとコンポーネントが再レンダリングされる
setCount() を呼ぶと、Reactがコンポーネントを再レンダリングし、画面が更新されます。通常の変数(
let count = 0)では画面が更新されません。
Step 2数値の状態管理
React(JSX)
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>
);
}
前の値を元に更新する場合は関数形式を使う
連続して更新する場合、setCount(count + 1) だと古い値を参照する可能性があります。setCount(prev => prev + 1) のように関数形式を使うと安全です。
Step 3文字列の状態管理(フォーム)
React(JSX)
function SearchForm() {
const [query, setQuery] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
console.log('検索:', query);
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="検索ワードを入力"
/>
<button type="submit">検索</button>
</form>
);
}
Step 4配列の状態管理
React(JSX)
function TodoList() {
const [todos, setTodos] = useState([]);
const [input, setInput] = useState('');
// 追加
const addTodo = () => {
setTodos([...todos, input]); // スプレッド構文で新しい配列を作る
setInput('');
};
// 削除
const removeTodo = (index) => {
setTodos(todos.filter((_, i) => i !== index));
};
return (
<div>
<input value={input} onChange={(e) => setInput(e.target.value)} />
<button onClick={addTodo}>追加</button>
<ul>
{todos.map((todo, i) => (
<li key={i}>
{todo}
<button onClick={() => removeTodo(i)}>削除</button>
</li>
))}
</ul>
</div>
);
}
配列やオブジェクトは直接変更しない
todos.push(item) のように直接変更してはいけません。必ず新しい配列/オブジェクトを作って
setTodos() に渡してください。
Step 5オブジェクトの状態管理
React(JSX)
function UserForm() {
const [user, setUser] = useState({
name: '',
email: '',
age: 0,
});
const handleChange = (e) => {
setUser({
...user, // 既存のプロパティをコピー
[e.target.name]: e.target.value, // 変更された項目だけ上書き
});
};
return (
<form>
<input name="name" value={user.name} onChange={handleChange} />
<input name="email" value={user.email} onChange={handleChange} />
<input name="age" type="number" value={user.age} onChange={handleChange} />
</form>
);
}
Step 6useStateの注意点
| ルール | 説明 |
|---|---|
| トップレベルでのみ呼ぶ | if文やfor文の中でuseStateを呼ばない |
| 関数コンポーネント内で呼ぶ | 通常の関数では使えない |
| stateを直接変更しない | 必ずset関数を使う |
| 更新は非同期 | setCountの直後にcountを参照しても古い値のまま |
まとめ
const [値, set関数] = useState(初期値)で状態を定義- set関数を呼ぶとコンポーネントが再レンダリングされる
- 前の値を元にする場合は関数形式
setPrev(prev => ...) - 配列・オブジェクトは直接変更せず、新しいものを作って渡す
- useStateはコンポーネントのトップレベルでのみ呼ぶ