I have a list of Dismissible/Checkbox tiles with local state. When I remove the first item, the checkbox state appears on the wrong row. Someone said I need Keys but the docs confuse me. When and which key?
When do I need Keys in Flutter? My list items swap state when I delete one.
Ask a question
Every post is reviewed first. Usually reviewed within 24 hours.
dev3 ·
0
1 reply
dev3 · Accepted answer
What happens
Flutter matches old and new widgets by type and position. If your tile is a StatefulWidget and you remove item 0, the element at position 0 is reused for the former item 1 along with its State (the checkbox value), while the widget configuration changes. State "sticks to the position", not to the data.
Fix: give each item a stable key
ListView.builder(
itemCount: todos.length,
itemBuilder: (context, i) {
final todo = todos[i];
return TodoTile(
key: ValueKey(todo.id), // unique, stable id from your data
todo: todo,
);
},
)
With a key, Flutter matches by identity, so removing one item removes exactly that element and its state.
Which key type
ValueKey(id): the default choice, based on a unique value.ObjectKey(obj): when the object itself is the identity.UniqueKey(): a new key every build; it forces recreation each time, so never create it insidebuildfor items you want to keep.GlobalKey: accesses a widget's State from elsewhere (Form validation, Scaffold) or moves a widget across the tree. Expensive, use rarely.PageStorageKey: preserves scroll position between navigation.
When you do not need keys
Stateless children, or lists that never reorder, insert or remove in the middle. Dismissible itself requires a key.
Pitfalls
- Using the index as the key defeats the purpose (same as no key).
- Duplicate keys among siblings throw "Duplicate keys found".
AnimatedSwitcherneeds a differing key on the child to animate between two widgets of the same type.
0