В библиотеке Radix UI для работы с вкладками
используется компонент Tabs, который обеспечивает доступ к
управлению состоянием выбранной вкладки через
контролируемый и неконтролируемый
режим.
value.defaultValue для первоначального выбора вкладки, после чего
состояние управляется внутренне библиотекой.Пример базового использования в контролируемом режиме:
import * as Tabs from '@radix-ui/react-tabs';
import { useState } from 'react';
function Example() {
const [activeTab, setActiveTab] = useState('tab1');
return (
<Tabs.Root value={activeTab} onValueCha nge={setActiveTab}>
<Tabs.List>
<Tabs.Trigger value="tab1">Вкладка 1</Tabs.Trigger>
<Tabs.Trigger value="tab2">Вкладка 2</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="tab1">Контент первой вкладки</Tabs.Content>
<Tabs.Content value="tab2">Контент второй вкладки</Tabs.Content>
</Tabs.Root>
);
}
Tabs.Rootvalue — текущая активная вкладка (только в
контролируемом режиме).defaultValue — вкладка, выбранная по умолчанию
(неконтролируемый режим).onValueChange — коллбек, вызываемый при изменении
активной вкладки, принимает новое значение.orientation — ориентация вкладок:
horizontal или vertical.activationMode — режим активации:
automatic (при наведении) или manual (только
по клику).Пример вертикальных вкладок с ручной активацией:
<Tabs.Root orientation="vertical" activationMode="manual">
<Tabs.List>
<Tabs.Trigger value="tab1">Вкладка 1</Tabs.Trigger>
<Tabs.Trigger value="tab2">Вкладка 2</Tabs.Trigger>
<Tabs.Trigger value="tab3">Вкладка 3</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="tab1">Контент первой вкладки</Tabs.Content>
<Tabs.Content value="tab2">Контент второй вкладки</Tabs.Content>
<Tabs.Content value="tab3">Контент третьей вкладки</Tabs.Content>
</Tabs.Root>
Radix UI позволяет динамически изменять активную вкладку программно.
Это достигается изменением состояния, связанного с value.
Можно реализовать автоматический переход на вкладку по событию,
например, после успешного API-запроса:
function DynamicTabs({ apiResult }) {
const [activeTab, setActiveTab] = useState('tab1');
useEffect(() => {
if (apiResult.success) {
setActiveTab('tab2');
}
}, [apiResult]);
return (
<Tabs.Root value={activeTab} onValueCha nge={setActiveTab}>
<Tabs.List>
<Tabs.Trigger value="tab1">Старт</Tabs.Trigger>
<Tabs.Trigger value="tab2">Результаты</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="tab1">Начальная вкладка</Tabs.Content>
<Tabs.Content value="tab2">Вкладка с результатами</Tabs.Content>
</Tabs.Root>
);
}
Radix UI автоматически обрабатывает фокус и клавиатурную навигацию между вкладками:
ArrowRight / ArrowDown — переход к
следующей вкладке.ArrowLeft / ArrowUp — переход к предыдущей
вкладке.Home — переход к первой вкладке.End — переход к последней вкладке.При ручном управлении состоянием важно синхронизировать
value с фокусом, чтобы обеспечить корректную навигацию с
клавиатуры.
Для оптимизации производительности используется проп
forceMount в Tabs.Content.
forceMount={true} — контент вкладки всегда монтируется,
даже если она неактивна.<Tabs.Content value="tab1" forceMount>
Контент первой вкладки всегда монтируется
</Tabs.Content>
Контролируемые вкладки легко интегрируются с
React Router или состоянием глобального менеджера,
например, Redux или Zustand:
import { useStore } from './store';
function RouterTabs() {
const { currentTab, setCurrentTab } = useStore();
return (
<Tabs.Root value={currentTab} onValueCha nge={setCurrentTab}>
<Tabs.List>
<Tabs.Trigger value="home">Главная</Tabs.Trigger>
<Tabs.Trigger value="profile">Профиль</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="home">Контент главной</Tabs.Content>
<Tabs.Content value="profile">Контент профиля</Tabs.Content>
</Tabs.Root>
);
}
forceMount только для вкладок с дорогостоящей
логикой монтирования, иначе оставлять ленивую загрузку.orientation и activationMode
для улучшения UX и доступности.Управление активной вкладкой в Radix UI строится на комбинации состояния, пропов и встроенной доступности, что позволяет создавать как простые, так и сложные интерфейсы с динамическим контентом.