

useStateで配列を更新する方法
ReactのuseStateで配列(Array)を管理する場合、オブジェクトの時と同様に**「元の配列を直接変更せず、新しい配列を作って上書きする」**ことが原則です。
そのため、push() や splice() といったメソッドは、元の配列を直接書き換えてしまう(破壊的変更)ため、Reactの状態更新では使いません。
代わりに、スプレッド構文(...)や filter(), map() といった「新しい配列を返す」メソッドを使います。
説明の流れ
この記事では、配列の操作で頻繁に使われる、以下の4つのパターンについてサンプルコードを紹介します。
・新しい要素を最後に追加 (push の代わりに)
・配列の特定の項目を更新 (map を使用)
・指定した順番(インデックス)に要素を挿入 (splice の代わりに)
・配列から特定の項目を削除 (filter を使用)
1. 配列の末尾に要素を追加する(push の代替)
push の代わりに、スプレッド構文を使って新しい配列を作ります。これが最も一般的です。
const [items, setItems] = useState(['りんご', 'みかん']);
const addItem = () => {
// 元の配列(...items)を展開し、末尾に新しい要素を追加した「新しい配列」を作る
setItems([...items, 'バナナ']);
};
// 実行後のitems: ['りんご', 'みかん', 'バナナ']
2. 配列内の特定の項目を更新する (map)
配列の中の特定のオブジェクトだけを更新したい場合は、map() メソッドを使います。map() も新しい配列を返すメソッドです。
const [tasks, setTasks] = useState([
{ id: 1, text: '牛乳を買う', done: false },
{ id: 2, text: '掃除をする', done: false },
]);
const toggleTask = (idToUpdate) => {
setTasks(
tasks.map(task => {
// 更新したいidと一致した場合
if (task.id === idToUpdate) {
// taskオブジェクトを展開し、doneプロパティだけを上書きした「新しいオブジェクト」を返す
return { ...task, done: !task.done };
} else {
// それ以外の要素は、そのまま返す
return task;
}
})
);
};
// toggleTask(2) を実行後のtasks:
// [
// { id: 1, text: '牛乳を買う', done: false },
// { id: 2, text: '掃除をする', done: true } // ← ここが更新された
// ]
3. 配列の特定の位置に要素を挿入する (splice の代替)
破壊的変更を行う splice() の代わりに、slice() とスプレッド構文を組み合わせて、配列の途中に要素を挿入します。
例えば ['A', 'B', 'D'] という配列の2番目(インデックス 1 の位置)に C を追加して、 ['A', 'C', 'B', 'D'] にしたい場合の例です。
const [items, setItems] = useState(['A', 'B', 'D']);
const newItem = 'C'; // 追加したい新しい要素
const targetIndex = 1; // 2番目(インデックス1)に追加
const insertItem = () => {
setItems([
...items.slice(0, targetIndex), // 1. 挿入位置より「前」をコピー
newItem, // 2. 新しい要素を追加
...items.slice(targetIndex) // 3. 挿入位置「以降」をコピー
]);
};
// --- 処理の流れ ---
// items.slice(0, 1) は ['A'] を返す
// newItem は 'C'
// items.slice(1) は ['B', 'D'] を返す
//
// これらを ... で展開して新しい配列 [] に入れると:
// ['A', 'C', 'B', 'D'] になる
この方法は、元の配列を slice で2つの部分(挿入位置の前と、挿入位置以降)に分割します。
それらをスプレッド構文 ... で展開し、間に新しい要素を挟みます。
結果として、元の配列(items)を一切変更せず、完全に新しい配列を作ることができます。
(※もし「2番目の後(インデックス 2 の位置)」に追加したい場合は、slice(0, 2) と slice(2) になります。)
4. 配列から特定の項目を削除する (filter)
特定の項目を削除するには、filter() メソッドを使います。filter() は、条件に合う(trueになった)要素だけを集めた新しい配列を返すので、Reactと非常に相性が良いです。
const [users, setUsers] = useState([
{ id: 1, name: '佐藤' },
{ id: 2, name: '鈴木' },
{ id: 3, name: '高橋' },
]);
const deleteUser = (idToDelete) => {
// 削除したいidと一致しない( !== )ユーザーだけを集めて、新しい配列を作る
setUsers(users.filter(user => user.id !== idToDelete));
};
// deleteUser(2) を実行後のusers:
// [ { id: 1, name: '佐藤' }, { id: 3, name: '高橋' } ]
まとめ
useStateでの配列の更新は、「スプレッド構文やfilter, mapなどを使って、事前に加工した『新しい配列』を作り、それで状態を丸ごと上書きする」のが基本です。
どの操作も、イミュータビリティ(不変性)、つまり「元のデータを壊さずに、コピーを元に新しいデータを作る」というReactの基本ルールに従っているのがポイントです。
