データベースの用語一覧へ
このページの目次

不変更新とは?

最終更新:2026/08/18

3秒でわかる

元の配列オブジェクトを書き換えず、変更を反映した新しい値を作る更新のやり方。Reactで画面が再描画されない問題の対処法でもあります。

もう少し詳しく

どういうものか

不変更新は、既存の配列やオブジェクトの中身を直接書き換える代わりに、変更を反映した新しい値を作って差し替えるやり方です。pushspliceプロパティへの代入といった破壊的な操作を避け、mapfilterconcatスプレッド構文で新しい入れ物を組み立てます。

なぜ必要か

React をはじめとする多くの状態管理では、更新されたかどうかを参照の同一性で判定しています。同じ配列の中身だけを書き換えると、変更前と変更後で参照が同じままなので、ライブラリからは「何も変わっていない」と見えます。データは正しいのに画面だけ古いまま、という現象の大半はこれが原因です。

もうひとつは変更の追跡です。元の値が残っていれば、直前の状態と比べたり、取り消し機能を作ったりできます。あちこちから同じオブジェクトを書き換えると、どこで値が変わったのかを追えなくなります。

具体例

const todos = [ { id: 1, text: "牛乳を買う", done: false }, { id: 2, text: "請求書を出す", done: false }, ]; // 追加 const added = [...todos, { id: 3, text: "掃除", done: false }]; // 削除 const removed = todos.filter((t) => t.id !== 1); // 1件だけ更新する。該当以外はそのまま返す const toggled = todos.map((t) => t.id === 2 ? { ...t, done: !t.done } : t ); // 入れ子のオブジェクトは<a href="/glossary/layer" class="text-primary font-medium underline underline-offset-2 hover:text-primary-dark">階層</a>ごとに作り直す const state = { user: { name: "田中", prefs: { theme: "light" } } }; const next = { ...state, user: { ...state.user, prefs: { ...state.user.prefs, theme: "dark" }, }, };
// Reactで画面が更新されない典<a href="/glossary/data-type" class="text-primary font-medium underline underline-offset-2 hover:text-primary-dark">型</a>例 const [items, setItems] = useState([]); // 参照が変わらないので再描画されない items.push(newItem); setItems(items); // 新しい配列を渡すと再描画される setItems([...items, newItem]);

つまずきやすいところ

スプレッド構文でコピーされるのは最上位の1階層だけです。{ ...state } としても、state.user は元と同じオブジェクトを指し続けます。そのまま copy.user.name = "佐藤" と書くと元の値も変わり、コピーしたつもりが変わっていない、という分かりにくい不具合になります。入れ子は階層ごとに展開します。

もうひとつは sortreverse です。この2つは新しい配列を返すように見えて、実際は元の配列を並べ替えたうえで同じ配列を返します。[...items].sort() のように、先にコピーしてから並べ替えます。

似た用語との違い

内容
不変更新新しい値を作って差し替える更新のやり方
ミューテーション元の値をその場で書き換える操作
浅いコピー1階層だけ複製する。入れ子は共有されたまま
深いコピー入れ子まで丸ごと複製する。structuredClone など

知識のつながり

サイドバーと同じ推奨ルート・関連語を、まとめて確認できます。

現在地不変更新DB

LEARN BY DOING

この用語を、教材で使ってみる

直接関連する編と、その編を含むコースです。用語だけで終わらず、ブラウザ上で実際に手を動かせます。

このコースが入っている学習分野

Reactコースの全編を見る