Когда и почему нужно использовать key в LazyColumn/LazyRow? Что будет, если не использовать?

Если коротко, то key в LazyColumn/LazyRow нужен, чтобы Compose понимал, какой элемент списка “кто есть кто” при вставках/удалениях/перестановках.
Без правильных ключей начинают прыгать remember-состояния, анимации, фокус и т.п.

Что делает key в LazyColumn/LazyRow

key — это уникальный идентификатор элемента в пределах списка. Compose использует его, чтобы:

  1. Понимать, что элемент с id=5 — это тот же элемент, что и раньше, только, например, сдвинулся на другую позицию.
  2. Переиспользовать слоты / состояние / анимации именно этого элемента, а не рандомно(!).
LazyColumn {
    items(
        items = users,
        key = { user -> user.id } // вот тут
    ) { user ->
        UserRow(user)
    }
}

//  Или

LazyColumn {
    items(users, key = { it.id }) { user -> ... }
}

Ключ должен быть:

  • Стабильным — не меняться для одного и того же логического элемента (например, user.id).
  • Уникальным среди элементов — иначе Compose будет путать.

Идеальный кандидатом может быть id из модели (id: Long, UUID, String, и т.п.).

Обязательно (или очень желательно) использовать key, когда:

  • список меняется: элементы добавляются/удаляются/переставляются
  • у элемента есть внутреннее состояние:
    • remember
    • rememberSaveable
    • анимации (animate*AsState, AnimatedVisibility)
    • фокус (TextField внутри)

Что будет, если key не задать?

Если key не указан, то LazyColumn по умолчанию использует индекс элемента в списке как ключ. И это ломает консистентность UI, когда нужно отсортировать-переставить список, вставить элемент в начало/середину, удалить элемент.

Пример:

//Было
index: 0   1   2
user:  A   B   C
key:   0   1   2

//Стало (вставили нового пользователя D в начало)
index: 0   1   2   3
user:  D   A   B   C
key:   0   1   2   3

С точки зрения Compose: «старый A с key=0» => теперь это «D с key=0», «старый B с key=1» => «теперь A с key=1».

И результате получаем:

  • remember внутри айтема начинает «переезжать» с одного пользователя на другого
  • скролл может дергаться при сложных обновлениях
  • анимации/фокус/selection «перескакивают»

Когда key не обязателен

Можно НЕ заморачиваться с key, если:

  • список не меняет порядок, только полностью заменяется (items(newList) без insert/remove в середине)
  • элементы простые, без локального remember (просто Text, Icon и т.п.)
  • список маленький и статичный (меню настроек, список из 3–5 пунктов, редко меняется)

Но даже там не навредит указать key = id, если он всё равно есть.


Опубликовано

в

,

от

Метки: