DEV3 Technologies home

When do I need Keys in Flutter? My list items swap state when I delete one.

Flutter helpSolved0 views
dev3 ·

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?

#flutter#keys#listview

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 inside build for 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".
  • AnimatedSwitcher needs a differing key on the child to animate between two widgets of the same type.
0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.