React Aria предоставляет набор хуков и утилит для создания доступных пользовательских интерфейсов. Среди них ключевую роль играют возможности фильтрации и поиска, которые позволяют реализовать динамическую подстройку контента под ввод пользователя с соблюдением стандартов доступности (ARIA).
Фильтрация и поиск обычно применяются в компонентах типа списков, выпадающих меню, таблиц или комбинированных полей ввода. Основной принцип работы заключается в разделении логики состояния и представления: React Aria предоставляет доступные события, свойства и методы управления, а визуальное оформление остаётся на стороне разработчика.
useFilteruseFilter — это утилита для фильтрации коллекций
элементов на основе строки поиска. Она возвращает функцию
contains, которая может использоваться для проверки,
соответствует ли элемент заданному фильтру.
Пример использования:
import {useFilter} from '@react-aria/i18n';
const {contains} = useFilter({sensitivity: 'base', ignoreCase: true});
const filteredItems = items.filter(item => contains(item.name, searchTerm));
Параметры useFilter:
sensitivity: Определяет чувствительность к регистру и
диакритическим знакам. Возможные значения: 'base',
'accent', 'case', 'variant'.ignoreCase: Булево значение, указывающее игнорировать
ли регистр при сравнении.Использование useFilter упрощает реализацию поиска без
необходимости вручную писать функции сравнения и заботиться о
локализации.
useComboBox и
фильтрацияДля выпадающих списков с поиском (ComboBox) React Aria
предоставляет хук useComboBox, который можно интегрировать
с useFilter для динамического отбора элементов.
Пример:
import {useComboBoxState} from '@react-stately/combobox';
import {useComboBox} from '@react-aria/combobox';
import {useFilter} from '@react-aria/i18n';
function SearchableComboBox({items}) {
const {contains} = useFilter({sensitivity: 'base'});
const state = useComboBoxState({
items,
defaultFilter: (item, inputValue) => contains(item.name, inputValue),
});
const ref = React.useRef();
const {inputProps, listBoxProps, labelProps} = useComboBox({inputRef: ref}, state);
return (
{state.isOpen && (
{state.filteredItems.map(item => (
- {item.name}
))}
)}
);
}
Здесь defaultFilter использует функцию
contains для проверки соответствия каждого элемента
введённой строке поиска.
React Aria поддерживает фильтрацию не только по простым строкам, но и
по более сложным структурам. Для этого можно использовать кастомные
функции фильтрации в сочетании с useComboBoxState или
useListState:
const customFilter = (item, inputValue) => {
const nameMatch = contains(item.name, inputValue);
const descriptionMatch = contains(item.description, inputValue);
return nameMatch || descriptionMatch;
};
const state = useListState({
items,
defaultFilter: customFilter,
});
Такой подход позволяет искать элементы по нескольким полям одновременно, поддерживая гибкость интерфейса.
При работе с большими коллекциями важно учитывать производительность фильтрации:
React.useMemo,
чтобы не пересчитывать результат при каждом ререндере.react-virtual или аналогичные
библиотеки).Пример с мемоизацией:
const filteredItems = React.useMemo(() => {
return items.filter(item => contains(item.name, searchTerm));
}, [items, searchTerm, contains]);
React Aria гарантирует корректное применение ARIA-атрибутов для компонентов поиска и фильтрации:
aria-activedescendant для указания текущего выбранного
элемента в списке.aria-controls для связи поля ввода с контейнером
списка.aria-expanded для отражения состояния раскрытия
списка.aria-label или aria-labelledby для
описания назначения поля поиска.Правильное использование этих атрибутов обеспечивает поддержку клавиатурной навигации и совместимость с экранными читалками.
useFilter учитывает локальные правила сортировки и поиска,
позволяя корректно работать с языками, где есть диакритические
знаки.filterFn в useListState или
useComboBoxState для реализации сложных алгоритмов поиска
(регулярные выражения, fuzzy search).