# const Constructors and Keys — Flutter

Source: https://www.skillbyai.com/en/flutter/w-keys

> Cheaper rebuilds and correct identity.

## Helping the framework match widgets

Marking a widget `const` (when all its arguments are constants) creates a single canonical instance; Flutter can see it is identical to the previous one and skip rebuilding that subtree. **Keys** control identity: by default Flutter matches old and new widgets in a list by **type and position**. When items are reordered, inserted or removed, stateful children can end up attached to the wrong data. Giving each item a `ValueKey(item.id)` (or `ObjectKey`) lets Flutter match by identity instead. A `GlobalKey` is unique across the app and gives access to a widget's State or context, for example `GlobalKey<FormState>`; use it sparingly because it is more expensive.

## Keys in a reorderable list

Stable identity for stateful rows.

```dart
class TodoList extends StatelessWidget {
  const TodoList({super.key, required this.todos});
  final List<Todo> todos;

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: [
        for (final todo in todos)
          TodoTile(key: ValueKey(todo.id), todo: todo), // match by id, not position
        const Divider(), // const: identical instance every build
      ],
    );
  }
}
```

## Let the linter add const

The prefer_const_constructors and related lints (in package:flutter_lints) point out where const can be added; dart fix --apply can add many automatically.

**Quiz:** Why add a ValueKey to items in a list that can be reordered?

- [ ] Keys are required on every widget
- [ ] To make the list scroll faster
- [ ] To translate the items
- [x] So Flutter matches each widget and its state to the right item by identity

*Answer:* So Flutter matches each widget and its state to the right item by identity. Without keys, matching is by type and position, which breaks when order changes.
