Что такое локальные ключи?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
LocalKey - локальные идентификаторы для виджетов
LocalKey - базовый класс для ключей, которые идентифицируют виджеты только в пределах одного родительского виджета. Используется в 95% случаев для управления состоянием в списках.
Типы LocalKey
1. ValueKey - ключ по значению
List<String> items = ["Apple", "Banana", "Cherry"];
ListView(
children: items.map((item) => Dismissible(
key: ValueKey(item),
onDismissed: (direction) => setState(() => items.remove(item)),
child: ListTile(title: Text(item)),
)).toList(),
)
Каждый элемент привязан к своему значению. Если переупорядочить список, состояние сохраняется правильно.
2. ObjectKey - ключ по объекту
class User {
final int id;
final String name;
User(this.id, this.name);
}
List<User> users = [...];
ListView(
children: users.map((user) => ListTile(
key: ObjectKey(user),
title: Text(user.name),
)).toList(),
)
Объекты идентифицируются по ссылке, а не по значению.
3. UniqueKey - абсолютно уникальный ключ
Widgets(
children: [
Text("Item 1", key: UniqueKey()),
Text("Item 2", key: UniqueKey()),
],
)
Каждый вызов создаёт новый уникальный ключ. Используется редко.
Практический пример
class TodoList extends StatefulWidget {
@override
State<TodoList> createState() => _TodoListState();
}
class _TodoListState extends State<TodoList> {
List<String> todos = ["Task 1", "Task 2", "Task 3"];
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return Dismissible(
key: ValueKey(todos[index]),
onDismissed: (direction) {
setState(() => todos.removeAt(index));
},
background: Container(color: Colors.red),
child: ListTile(
title: Text(todos[index]),
),
);
},
);
}
}
Без ключей: если удалить первый элемент, состояние других элементов может перепутаться. С ValueKey: каждый элемент сохраняет своё состояние правильно.
Когда использовать ключи
Используй ключи в:
- Списках (ListView, ListView.builder)
- Сетках (GridView)
- Переупорядочиваемых элементах (ReorderableListView)
- Dismissible виджетах
- Анимированных списках
Ошибка: использование индекса как ключа
// Плохо! Индекс меняется при удалении
ListView(
children: items.asMap().entries.map((e) => ListTile(
key: ValueKey(e.key), // Индекс как ключ!
title: Text(e.value),
)).toList(),
)
// Хорошо! Используй уникальный ID
ListView(
children: items.map((item) => ListTile(
key: ValueKey(item.id), // Уникальный ID!
title: Text(item.name),
)).toList(),
)
Best Practice
- Используй ValueKey с уникальным ID (not индекс)
- Для объектов используй ObjectKey
- UniqueKey только в исключительных случаях
- Всегда добавляй ключи в списки и сетки
Локальные ключи - основной инструмент для правильного управления состоянием в коллекциях Flutter.