В библиотеке 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} обеспечивает сохранение состояния фокуса
при перерендере списка.isSelected и isFocused с конкретным элементом
коллекции.При изменении коллекции важно, чтобы ключи оставались уникальными и стабильными для уже существующих элементов. Например:
let items = [
{ id: "apple", name: "Apple" },
{ id: "banana", name: "Banana" }
];
// Добавляем новый элемент
items.push({ id: "cherry", name: "Cherry" });
Если ключи элементов будут пересчитываться заново (например, по
индексу массива), React Aria потеряет привязку состояний фокуса и
выделения, и все элементы будут восприниматься как новые. Использование
id как ключа предотвращает это.
Правильное использование ключей улучшает производительность:
id,
uuid), а не индексы массива.Ключи в React Aria — это основа для предсказуемого поведения компонентов при динамическом рендере коллекций. Их правильное использование гарантирует, что интерактивность и состояние компонентов сохраняются при любых изменениях интерфейса.