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

不変更新とは?

最終更新:2026/08/18

3秒でわかる

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

もう少し詳しく

どういうものか

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

なぜ必要か

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 = "佐藤" と書くと元の値も変わり、コピーしたつもりが変わっていない、という分かりにくい不具合になります。入れ子は階層ごとに展開します。

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

似た用語との違い

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

知識のつながり

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

現在地不変更新DB

LEARN BY DOING

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

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

Reactコースの全編を見る