Хук useTable является ключевым инструментом для создания
доступных и функциональных таблиц в приложениях на
React с библиотекой React Aria. Он
обеспечивает управление фокусом, выделением, сортировкой и навигацией по
строкам и ячейкам таблицы, полностью соответствуя стандартам доступности
ARIA.
Для начала работы с useTable необходимо импортировать
его вместе с сопутствующими хуками и компонентами:
import { useTable, useTableState } from '@react-stately/table';
import { useTable as useTableAria } from '@react-aria/table';
import { useFocusRing } from '@react-aria/focus';
useTable работает в связке с state
таблицы, который создается с помощью useTableState.
State управляет данными, сортировкой и выделением
строк.
const state = useTableState({
columns: [
{ name: 'Имя', key: 'name' },
{ name: 'Возраст', key: 'age' },
{ name: 'Город', key: 'city' }
],
items: [
{ id: '1', name: 'Иван', age: 30, city: 'Москва' },
{ id: '2', name: 'Анна', age: 25, city: 'Санкт-Петербург' }
]
});
После создания состояния вызывается useTableAria,
который возвращает необходимые props для таблицы и её
элементов.
const { tableProps, gridProps } = useTableAria({ /* props */ }, state);
Таблица состоит из следующих ключевых компонентов:
tableProps.rowProps.Пример рендеринга:
<table {...tableProps}>
<thead>
<tr>
{state.collection.headerRows[0].childNodes.map(column => (
<th key={column.key} {...column.props}>
{column.rendered}
</th>
))}
</tr>
</thead>
<tbody>
{state.collection.items.map(item => (
<tr key={item.key} {...item.props}>
{item.childNodes.map(cell => (
<td key={cell.key} {...cell.props}>
{cell.rendered}
</td>
))}
</tr>
))}
</tbody>
</table>
React Aria предоставляет интеграцию с фокусом через
useFocusRing. Это позволяет визуально выделять активную
строку или ячейку.
const { isFocusVisible, focusProps } = useFocusRing();
<td {...cell.props} {...focusProps} className={isFocusVisible ? 'focused' : ''}>
{cell.rendered}
</td>
Для поддержки выбора строк и навигации между ними используется
состояние selectionMode в useTableState:
const state = useTableState({
selectionMode: 'multiple', // single, multiple, none
columns: [...],
items: [...]
});
Выделенные строки автоматически отслеживаются в
state.selectionManager.
useTableState позволяет задавать сортировку по
столбцам:
const state = useTableState({
columns: [
{ name: 'Имя', key: 'name', allowsSorting: true },
{ name: 'Возраст', key: 'age', allowsSorting: true }
],
items: [...],
sortDescriptor: { column: 'name', direction: 'ascending' }
});
Для сортируемых заголовков следует использовать
column.props с aria-sort, который
автоматически управляется React Aria:
<th {...column.props} onCl ick={() => state.sort(column.key)}>
{column.rendered}
</th>
useTable автоматически добавляет все необходимые
ARIA атрибуты:
role="table" для контейнераrole="row" для строкrole="columnheader" и role="cell" для
заголовков и ячеекaria-selected, aria-sort и
aria-multiselectableЭто гарантирует корректное взаимодействие с экранными читалками и клавиатурной навигацией.
Для больших таблиц рекомендуется использовать виртуализацию с
react-virtual или аналогами. Важно передавать
state.collection и props ячеек напрямую в виртуальные
рендеры, чтобы сохранялись все ARIA-атрибуты и фокус.
<Virtualizer
totalCount={state.collection.size}
overscan={5}
renderItem={(index) => {
const item = state.collection.getItem(index);
return (
<tr key={item.key} {...item.props}>
{item.childNodes.map(cell => (
<td key={cell.key} {...cell.props}>{cell.rendered}</td>
))}
</tr>
);
}}
/>
useTable предоставляет только логику и
доступность, поэтому визуальное оформление полностью
контролируется через CSS или сторонние UI-библиотеки. Важно
сохранять:
Пример базового CSS для выделенной строки:
tr[aria-selected="true"] {
background-color: #e0f7fa;
}
td.focused {
outline: 2px solid #0288d1;
}
useTable в React Aria обеспечивает создание полностью
доступных, управляемых и расширяемых таблиц с поддержкой всех ключевых
взаимодействий: выделения, сортировки, фокусировки и клавиатурной
навигации. Его интеграция с useTableState и
useFocusRing позволяет строить сложные интерфейсы,
соответствующие современным стандартам доступности.