What are `Key`s used for in Flutter, and when do you need them?
Show answer — try answering out loud first
Keys help Flutter identify widgets when it rebuilds the tree, so it correctly matches each widget with its state. You usually don't need them, but they become necessary when you reorder, add, or remove items from a list of stateful widgets, so the state doesn't get mixed up between items.
When Flutter rebuilds, it compares the new tree with the previous one to decide what to reuse. By default it compares by widget type and position. That works almost always, but it breaks when you change the order of same-type widgets that have state: Flutter can assign the wrong state to the wrong widget.
A Key gives each widget a stable identity so Flutter tracks it correctly even when it changes position.
Common types:
ValueKey: identity based on a value (for example, an id).ObjectKey: identity based on an object.UniqueKey: always-unique identity (forces Flutter to treat it as new).GlobalKey: global identity; lets you access the widget's state or position from outside. It's the most expensive one; use it with care.
import 'package:flutter/material.dart';
// In a reorderable list of stateful widgets, keys prevent
// the state from "sticking" to the wrong item.
class TaskList extends StatelessWidget {
final List<String> tasks;
const TaskList({super.key, required this.tasks});
@override
Widget build(BuildContext context) {
return Column(
children: [
for (final task in tasks)
ListTile(
key: ValueKey(task), // stable identity per task
title: Text(task),
),
],
);
}
}
Putting UniqueKey() on widgets inside a build "just in case." Since UniqueKey() generates a different key every time, you force Flutter to destroy and recreate the widget (and lose its state) on every rebuild. That kills performance and causes strange behavior. Keys are used intentionally, not by default.
"Keys help Flutter identify widgets when it rebuilds the tree, so it matches each widget with its correct state. Most of the time I don't need them, because Flutter compares by type and position. But when I have a list of stateful widgets and I reorder, add, or remove them, I use a
ValueKeywith something unique like an id so the state doesn't get mixed up between items. I reserveGlobalKeyfor cases where I need to access the state from outside, because it's more expensive."
You have a list of two stateful Checkboxes and, when you reorder them, the "checked" state stays in the wrong position. How do you fix it?
See answer
By assigning a stable, unique Key to each item, based on its identity (not its position). For example, key: ValueKey(item.id). That way Flutter tracks each Checkbox by its identity even when it changes place, and the state (checked/unchecked) travels with the correct item.