Ключи элементов

В библиотеке React Aria ключи элементов (key) играют критически важную роль при работе с коллекциями, интерактивными компонентами и динамическими списками. Они позволяют библиотеке точно отслеживать состояние отдельных элементов и корректно управлять фокусом, выделением и анимацией при изменении структуры DOM.

Принцип работы ключей

Каждый элемент коллекции в React Aria должен иметь уникальный идентификатор, который остаётся стабильным между рендерами. Это необходимо, чтобы:

  • Сохранять состояние компонентов при динамических изменениях коллекции.
  • Избежать лишнего пересоздания элементов и потери фокуса.
  • Обеспечить корректную работу систем управления выделением и навигацией по клавиатуре.

React Aria использует ключи для ассоциации внутренних состояний с элементами интерфейса. Если ключ изменяется между рендерами, библиотека рассматривает элемент как новый, что приводит к сбросу всех состояний, включая фокус и активные стили.

Выбор ключей

Наиболее безопасным подходом является использование уникальных идентификаторов данных, а не индексов массива:

import { useListState } from "@react-stately/list";

let items = [
  { id: "apple", name: "Apple" },
  { id: "banana", name: "Banana" },
  { id: "cherry", name: "Cherry" }
];

let state = useListState({ items });

return (
  <ul>
    {state.collection.map(item => (
      <li key={item.key}>{item.rendered}</li>
    ))}
  </ul>
);
  • item.key здесь соответствует уникальному идентификатору элемента.
  • Использование индексов массива вместо уникальных ключей может привести к неожиданным пересозданиям компонентов при удалении или перестановке элементов.

Ключи и управление фокусом

React Aria автоматически управляет фокусом и выделением для компонентов типа ListBox, Menu, Tabs, если каждый элемент имеет стабильный ключ. Пример с выбором элемента в списке:

import { useListState } from "@react-stately/list";
import { useListBox, useOption } from "@react-aria/listbox";

function ListBox({ items }) {
  let state = useListState({ items });
  let ref = React.useRef();
  let { listBoxProps } = useListBox({ selectionMode: "single" }, state, ref);

  return (
    <ul {...listBoxProps} ref={ref}>
      {state.collection.map(item => (
        <Option key={item.key} item={item} state={state} />
      ))}
    </ul>
  );
}

function Option({ item, state }) {
  let ref = React.useRef();
  let { optionProps, isSelected, isFocused } = useOption(
    { key: item.key },
    state,
    ref
  );

  return (
    <li
      {...optionProps}
      ref={ref}
      style={{
        background: isFocused ? "lightblue" : undefined,
        fontWeight: isSelected ? "bold" : undefined
      }}
    >
      {item.rendered}
    </li>
  );
}
  • key={item.key} обеспечивает сохранение состояния фокуса при перерендере списка.
  • React Aria использует ключи для синхронизации внутреннего состояния isSelected и isFocused с конкретным элементом коллекции.

Динамическое добавление и удаление элементов

При изменении коллекции важно, чтобы ключи оставались уникальными и стабильными для уже существующих элементов. Например:

let items = [
  { id: "apple", name: "Apple" },
  { id: "banana", name: "Banana" }
];

// Добавляем новый элемент
items.push({ id: "cherry", name: "Cherry" });

Если ключи элементов будут пересчитываться заново (например, по индексу массива), React Aria потеряет привязку состояний фокуса и выделения, и все элементы будут восприниматься как новые. Использование id как ключа предотвращает это.

Влияние на производительность

Правильное использование ключей улучшает производительность:

  • Минимизирует количество операций на DOM при изменении коллекции.
  • Позволяет React Aria повторно использовать существующие элементы и состояния.
  • Обеспечивает стабильность при работе с компонентами с тяжелыми визуальными элементами или анимациями.

Резюме по ключам в React Aria

  • Каждый элемент коллекции должен иметь уникальный и стабильный ключ.
  • Использовать данные с уникальными идентификаторами (id, uuid), а не индексы массива.
  • Ключи напрямую влияют на состояние фокуса, выделения и внутренние механизмы коллекций.
  • Стабильные ключи обеспечивают корректную работу динамических списков, вкладок, меню и других интерактивных компонентов.

Ключи в React Aria — это основа для предсказуемого поведения компонентов при динамическом рендере коллекций. Их правильное использование гарантирует, что интерактивность и состояние компонентов сохраняются при любых изменениях интерфейса.