ReactのuseState更新関数に関数を渡す方法を解説!前回の値を利用して安全に状態更新
生徒
「先生、ReactでuseStateの値を前の値を使って更新したいときってどうしたらいいですか?」
先生
「useStateの更新関数には関数を渡す方法があります。これを使うと、前回の値を安全に使って新しい値を計算できます。」
生徒
「関数を渡すって具体的にはどういうことですか?」
先生
「setStateに直接値を渡すのではなく、前回の値を引数として受け取り、それをもとに新しい値を返す関数を渡す方法です。」
1. useStateの基本的な値の更新
ReactのuseStateは、画面に表示する数値や文字などの状態を管理するための仕組みです。 初心者の方は「変数の代わり」と考えると分かりやすいでしょう。 useStateを使うと、ボタンを押したときや入力が変わったときなどに、 画面の内容を自動で更新できるようになります。
基本的な使い方では、setState関数に新しい値をそのまま渡して状態を更新します。 これは直感的で分かりやすい方法ですが、更新処理が重なった場合や、 処理のタイミングがずれる場面では、意図しない値になることがある点に注意が必要です。
import React, { useState } from "react";
function App() {
const [count, setCount] = useState(0);
return (
<div>
<p>カウント: {count}</p>
<button onClick={() => setCount(count + 1)}>
カウントを増やす
</button>
</div>
);
}
export default App;
このように、useStateの基本的な更新方法はとてもシンプルです。 まずは「setStateに新しい値を渡すと画面が更新される」という流れを、 しっかり理解することが大切です。 次の項目では、この方法で起こりやすい注意点について詳しく見ていきます。
2. 更新関数に関数を渡す方法
前回の値を安全に使って更新したいときは、setStateに「新しい値」ではなく「計算するための関数」を渡します。 この関数は、直前の状態を引数として受け取り、その値をもとに次の状態を作って返します。 たとえばカウンターのように「前の数に一を足す」といった更新では、前回の値を確実に参照できる書き方が大切です。 連続クリックや処理が重なった場面でも、更新がずれにくくなるのがポイントです。
関数に渡される引数の名前は自由ですが、よくある書き方としてprevCountのように、 「前の値だと分かる名前」にしておくと読みやすくなります。 初めて見る方は、prevCountを「ひとつ前のcount」と置き換えて読むと理解しやすいでしょう。
import React, { useState } from "react";
function App() {
const [count, setCount] = useState(0);
const increment = () => {
setCount((prevCount) => prevCount + 1); // prevCountが前回の値
};
return (
<div>
<p>カウント: {count}</p>
<button onClick={increment}>カウントを増やす</button>
</div>
);
}
export default App;
この方法は、足し算だけでなく「前の文字に追加する」「前の配列に要素を足す」などにも応用できます。 まずは、更新関数に関数を渡すと「前回の値を受け取ってから更新できる」という流れを、 ここでしっかり身につけておきましょう。
3. 関数を渡すメリット
直接値を渡す方法と比べて、更新関数に関数を渡す書き方には、初心者にとっても分かりやすいメリットがあります。 いちばん大きいのは「前回の値を必ず使って計算できる」ことです。 ボタンを素早く連打したときや、処理が重なって実行されるような場面でも、 直前の状態を受け取ってから更新するため、数がずれたり意図しない結果になったりしにくくなります。 つまり、状態更新のルールが安定し、バグを減らしやすい書き方になります。
また、コードを読む人にとっても「前の値から次の値を作っている」と意図が伝わりやすく、 どのタイミングでも同じ結果になりやすいという安心感があります。 ちょっとしたカウンターでも、この習慣を身につけておくと、 入力フォームやリストの追加など、Reactのさまざまな場面で役立ちます。
- 連続クリックや処理の重なりがあっても、前回の状態をもとに正しく更新できる
- 状態更新の流れが安定し、思いがけないズレや更新漏れを防ぎやすくなる
- 「前の値から次の値を作る」形がはっきりし、読みやすく予測しやすいコードになる
たとえば、同じボタンでも「今の値に一を足す」のではなく「前回の値に一を足す」と書けるため、 状態管理の考え方が自然に身につきます。 まずはこのメリットを理解しておくと、useStateの更新がぐっと安心して書けるようになります。
4. 応用例:カウンターの複数増加
例えば、ボタンを押すと2回分カウントを増やす場合、関数を渡すことで確実に前回の値をもとに計算できます。
const incrementTwice = () => {
setCount(prevCount => prevCount + 1);
setCount(prevCount => prevCount + 1);
};
5. 配列やオブジェクトの更新でも使える
オブジェクトや配列を状態として管理している場合も、前回の状態を安全に参照して更新できます。例えば配列に要素を追加する場合です。
const [items, setItems] = useState([]);
const addItem = newItem => {
setItems(prevItems => [...prevItems, newItem]);
};
6. 初心者が気をつけるポイント
- setStateに直接値を渡すと、非同期処理で前回の値を参照できないことがある
- 前回の値を使う場合は必ず関数を渡す
- 配列やオブジェクトを更新するときも関数を使うと安全
- 複数回更新するときも前回の状態を正しく引き継げる