楽観更新の並び替えは部分パッチで直し、次はorder外部化を試す
今回実際にやったのは、並び替え時の楽観更新を「表示中データで全体を置換する方式」から「既存キャッシュに対する部分パッチ方式」へ変えたこと。これで、未表示要素の順序や存在が壊れる症状を抑えられた。
- 変更前の問題 — 表示中の配列をそのまま全体へ反映してしまい、フィルタ/ページング外の要素に副作用が出る
// NG: visibleRows だけで全体を再構築
setQueryData(key, visibleRows)
- 実際に入れた修正 — id 一致の既存要素だけ差し替える。未表示要素は保持する
const updates = new Map(visibleRows.map((row) => [row.id, row]))
setQueryData(key, (current) =>
current.map((row) => updates.get(row.id) ?? row)
)
今回の学び — 一覧UIの optimistic update は、全体同期ではなく「既存キャッシュへの局所変更」として扱うと崩れにくい
次に試す改善案(未実施) — order だけを外部化して、実体データと順序責務を分離する
// entities と order を分離して管理するイメージ
state = {
entitiesById: Record<string, Item>,
orderedIdsByView: Record<ViewKey, string[]>,
}
この形にすると、DnD の楽観更新は orderedIdsByView だけを更新すればよく、未表示要素や別ビューへの副作用を抑えやすい。次回はこの設計で比較する。