swiftui · note · identity
ForEach Identity Debug Checklist
Context
When ForEach identity is unstable, SwiftUI updates still compile but behavior degrades: rows reset, animations snap, and state appears to jump between items.
The snippet
ForEach(items.indices, id: \.self) { index in
ItemRow(item: items[index])
}
Why this works
This pattern only works safely for fully static collections. As soon as you reorder, filter, insert, or delete, index identity no longer represents logical item identity.
Use this checklist:
- Does each model have one stable ID from data creation?
- Is
ForEachkeyed by that model ID, not index? - Are IDs preserved across fetch/merge steps?
- Are you accidentally recreating IDs in mappers?
If any answer is “no”, fix identity before debugging animation or state wrappers.
Use it when…
- list rows reset unexpectedly after updates
- row-level controls keep wrong state after sorting/filtering
- insert/delete animations feel like full row replacement
Avoid it when…
- collection is static and identity churn is impossible
- you already have stable
Identifiablemodels and deterministic transforms - the bug is clearly ownership-related rather than list reconciliation
Takeaway: Debug list behavior by validating identity first, then state ownership.
Next steps
If you want the deeper model behind this checklist, continue with: