Что такое Key?
Key — идентификатор виджета, который помогает Flutter сопоставлять новые виджеты с уже существующими элементами при обновлении дерева.
Как Flutter сопоставляет виджеты без ключей
Когда Flutter получает новый список виджетов при ребилде, он пытается сопоставить их с существующими элементами по позиции и типу (runtimeType). Если порядок элементов изменился или виджеты одного типа поменялись местами, состояние может перескочить на другой элемент — потому что Flutter повторно использовал элемент по индексу.
Пример проблемы без ключей
import 'package:flutter/material.dart';
class ItemWidget extends StatefulWidget {
final String title;
ItemWidget(this.title);
@override
_ItemWidgetState createState() => _ItemWidgetState();
}
class _ItemWidgetState extends State<ItemWidget> {
int counter = 0;
@override
Widget build(BuildContext context) {
return ListTile(
title: Text('${widget.title} ($counter)'),
trailing: IconButton(
icon: Icon(Icons.add),
onPressed: () => setState(() => counter++),
),
);
}
}
При перестановке элементов состояния могут перепутаться
Типы
▫️ValueKey<T> — ключ по значению (идеален для id-модели).
▫️ObjectKey — сравнение по == объекта.
▫️UniqueKey — каждый раз новый ключ (заставляет создать новый Element; сбрасывает состояние).
▫️GlobalKey — глобальная уникальность + доступ к State/Context; использовать экономно (дорогой).
Когда использовать
▫️Динамические списки с добавлением/удалением/реордером — ValueKey(id).
▫️Формы, доступ к State извне — GlobalKey (только при необходимости).
Когда не нужен
В статичных списках и простых элементах без внутреннего состояния. Не ставьте ключи на всякий — если они лишние, то усложняют и могут ухудшать производительность.
Рекомендации
▫️Для сущностей с постоянным id — ValueKey(id).
▫️Если хотите сбросить состояние — UniqueKey.
▫️GlobalKey — только для специфических задач (формы, навигация, тесты).
▫️Если состояние перескакивает — сначала добавьте ключи, а не перестраивайте архитектуру.
И помните, правильный выбор ключа решает распространенные баги с состоянием 🦋
