Key each item to reorder
One keyed boundary per item lets a sort glide instead of jump.
React docsreact.dev
It's important to properly use keys to preserve identity when reordering lists.
From vercel-react-view-transitions, SKILL.md.
Sort the same list
Change the sort a few times.
One for the whole listBad
<ViewTransition><List />One per itemGood
<ViewTransition key={item.id}>const [sort, setSort] = useState('newest');
const [optimisticSort, setOptimisticSort] = useOptimistic(sort);
function cycleSort() {
const nextSort = getNextSort(optimisticSort);
startTransition(() => {
setOptimisticSort(nextSort); // label: before the snapshot, no animation
setSort(nextSort); // list: between snapshots, animates
});
}
<button onClick={cycleSort}>Sort: {LABELS[optimisticSort]}</button>
{items.sort(comparators[sort]).map(item => (
<ViewTransition key={item.id}><ItemCard item={item} /></ViewTransition>
))}
Why it matters, pros and cons
Why it matters
A boundary per item gives each row its own snapshot, so the browser can move it. One boundary around the list can only cross-fade the whole block.
Pros
- Rows travel; the new order is legible.
- Adds and removes get enter and exit.
- Server sorting via
router.replaceworks the same.
Cons
- No wrapper
divbetweenmapand the boundary. default="none"on items stops the glide.- Optimistic order resolves before the snapshot; it won't animate.