← Назад к вопросам

Что такое локальные ключи?

1.7 Middle🔥 131 комментариев
#Flutter виджеты#ООП и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

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.

Что такое локальные ключи? | PrepBro