起きたこと
Reactでリストを日付順に並べ替えて表示する処理をAIに書いてもらったところ、なぜか元のstateの並び順まで変わってしまう不具合が起きました。
const [items, setItems] = useState(originalItems);
function showSorted() {
const sorted = items.sort((a, b) => a.date.localeCompare(b.date));
console.log(sorted);
}
sortedだけを使うつもりだったのに、なぜかitems(stateの中身)自体の並び順も変わっていました。
原因: Array.prototype.sort() は破壊的メソッド
sort()は新しい配列を返しているように見えますが、実際には元の配列を直接書き換えて、その配列への参照を返しているだけです。
const original = [3, 1, 2];
const result = original.sort();
console.log(result); // [1, 2, 3]
console.log(original); // [1, 2, 3] ← 元の配列も変わっている
console.log(result === original); // true(同じ配列を指している)
React の state は「同じ参照のまま中身だけ変える」ことを想定していません。items.sort() は items 自体を書き換えてしまうため、React が変更を検知できず、意図しないタイミングで表示が崩れたり、逆に再レンダリングされるべき場面で更新が起きなかったりします。
実際に確認した挙動
| 操作 | 元の配列は変わるか | 戻り値は新しい配列か |
|---|---|---|
array.sort() |
変わる(破壊的) | いいえ(同じ参照) |
[...array].sort() |
変わらない | はい(新しい配列) |
array.toSorted()(ES2023〜) |
変わらない | はい(新しい配列) |
sort() と名前の似ている map() や filter() は非破壊的(新しい配列を返す)なので、AIが生成したコードでも「配列を扱うメソッドは基本的に非破壊的」という思い込みで見落としがちです。
AIへの頼み方をどう変えるか
悪い例
「日付順に並べ替える処理を書いて」
これだと array.sort() をそのまま使ったコードが返ってきがちです。破壊的かどうかに触れる指定がないためです。
良い例
「日付順に並べ替える処理を書いてください。元の配列は変更せず、新しい配列を返すようにしてください」
function showSorted() {
const sorted = [...items].sort((a, b) => a.date.localeCompare(b.date));
console.log(sorted);
// items 自体は変更されない
}
スプレッド構文でコピーしてから sort() するだけで、元の配列を安全に保てます。
まとめ
-
Array.prototype.sort()は元の配列を直接書き換える破壊的メソッド - Reactのstateに対して直接呼ぶと、意図しない再レンダリング挙動につながる
-
[...array].sort()でコピーしてから並べ替えるか、toSorted()(対応環境なら)を使う - AIに頼むときは「元の配列は変更しない」と明示すると安全なコードが返ってきやすい
この動作はJavaScriptの言語仕様(ECMAScript)に基づくもので、reverse() や splice() も同様に破壊的メソッドです。導入時は挙動を実際に確認することをおすすめします。
なお、この内容はプログラミング学習を始めたばかりの方には少し高度かもしれません。中上級者の方は、初心者の知り合いへの紹介や社内研修の参考としてどうぞ。
未経験から Next.js + Supabase + Claude Code で Webアプリを公開するまで
全20セッションの教材付きプランで、面談なしで今日から学習を始められます。
- 教材完全版+メンタリング(月5,500円・いつでも解約OK)→ https://menta.work/plan/20251?ref=qiita
- 無料の教材体験版(最初の数セッション)→ https://github.com/ayies128/next-ai-camp-trial
- YouTube『AIエンジニア情報局』(別運営・AI×開発ニュースを5分でキャッチアップ)→ https://www.youtube.com/channel/UC1rXVD9WYsQPQEWZyd-A1KA/?ref=qiita