Создание сайдбар-навигации в React с Material UI и react-router
TL;DR
Коротко: пошаговое руководство по созданию горизонтально-фиксированного сайдбара в React, который содержит ссылки с иконками Material UI и маршрутизацию через react-router-dom. Включены готовые примеры кода для navData, Sidenav, CSS-модуля, конфигурации роутов и советы по доступности, тестированию и оптимизации.
Введение

Сайдбар (боковая навигация) — это вертикальный список ссылок, часто с иконками. В React такой компонент удобно собрать из массива данных и отрисовать через map. В этом руководстве вы создадите коллапсируемый сайдбар со сменой иконки, локально-скоупед CSS-модулями и маршрутизацией через react-router-dom.
Важно: если у вас уже есть проект React, пропустите раздел о создании приложения и переходите к компонентам.
Что вы получите
- Коллапсируемый сайдбар с иконками Material UI
- Маршрутизация через react-router-dom (NavLink)
- Локальные стили через CSS Modules
- Проверки доступности и короткий план тестирования
Основные термины
- NavLink: компонент из react-router-dom для ссылок, которые знают активный маршрут.
- CSS Modules: способ писать локально-скоупед CSS-классы в React.
- Коллапс/разворачивание: изменение ширины сайдбара и видимости текста.
1. Создание React-приложения
Если проекта нет, создайте быстрый шаблон при помощи create-react-app:
npx create-react-app react-sidenavЭто создаст папку react-sidenav с преднастроенной сборкой и зависимостями. Чтобы упростить стартовую структуру, откройте src/App.js и замените содержимое на базовый шаблон:
import './App.css';
function App() {
return (
);
}
export default App;2. Структура проекта (рекомендуемая)
Пример дерева файлов проекта, которое мы будем использовать:
- src/
- Components/
- Sidenav.js
- sidenav.module.css
- Pages/
- Home.js
- Explore.js
- Statistics.js
- Settings.js
- lib/
- navData.js
- App.js
- index.js
- Components/
Эта структура разделяет логику навигации, страницу и данные навигации.
3. Данные навигации (navData)
Создайте папку lib и файл navData.js. В нем хранится массив объектов с иконкой, текстом и ссылкой.
import HomeIcon from '@mui/icons-material/Home';
import TravelExploreIcon from '@mui/icons-material/TravelExplore';
import BarChartIcon from '@mui/icons-material/BarChart';
import SettingsIcon from '@mui/icons-material/Settings';
export const navData = [
{
id: 0,
icon: ,
text: "Home",
link: "/"
},
{
id: 1,
icon: ,
text: "Explore",
link: "explore"
},
{
id: 2,
icon: ,
text: "Statistics",
link: "statistics"
},
{
id: 3,
icon: ,
text: "Settings",
link: "settings"
}
]Убедитесь, что установили Material UI и иконки:
npm install @mui/material @emotion/react @emotion/styled
npm install @mui/icons-material4. Компонент Sidenav
В папке Components создайте Sidenav.js. Компонент читает navData и рендерит элементы через NavLink. Полный пример Sidenav с коллапсом и переключателем состояния:
// In Sidenav.js
import React, { useState } from 'react';
import { NavLink } from 'react-router-dom';
import { navData } from "../lib/navData";
import KeyboardDoubleArrowLeftIcon from '@mui/icons-material/KeyboardDoubleArrowLeft';
import KeyboardDoubleArrowRightIcon from '@mui/icons-material/KeyboardDoubleArrowRight';
import styles from './sidenav.module.css';
export default function Sidenav() {
const [open, setOpen] = useState(true);
const toggleOpen = () => {
setOpen(!open);
}
return (
{navData.map(item => {
return (
{item.icon}
{item.text}
)
})}
)
}Примечание: в react-router-dom v6 у NavLink проп activeClassName заменён на стиль-пропс или функцию; в примере выше используется activeclassname для краткости — в вашем проекте замените на правильный синтаксис (см. советы по совместимости ниже).
5. CSS-модуль (sidenav.module.css)
Пример локальных стилей для сайдбара (в папке Components создайте sidenav.module.css):
.sidenav {
width: 250px;
transition: width 0.3s ease-in-out;
height: 100vh;
background-color: rgb(10,25,41);
padding-top: 28px;
}
.sidenavClosed {
composes: sidenav;
transition: width 0.3s ease-in-out;
width: 60px
}
.sideitem {
display: flex;
align-items: center;
padding: 10px 20px;
cursor: pointer;
color: #B2BAC2;
text-decoration: none;
}
.linkText {
padding-left: 16px;
}
.linkTextClosed {
composes: linkText;
visibility: hidden;
}
.sideitem:hover {
background-color: #244f7d1c;
}
.menuBtn {
align-self: center;
align-self: flex-start;
justify-self: flex-end;
color: #B2BAC2;
background-color: transparent;
border: none;
cursor: pointer;
padding-left: 20px;
}Совет: при использовании CSS Modules имена классов локализуются, что предотвращает конфликты.
6. Маршрутизация с react-router-dom
Установите пакет:
npm install react-router-dom@latestВ index.js оберните приложение BrowserRouter:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
);В App.js настройте маршруты и включите Sidenav:
import './App.css';
import Sidenav from './Components/Sidenav';
import Explore from "./Pages/Explore";
import Home from "./Pages/Home";
import Settings from "./Pages/Settings";
import Statistics from "./Pages/Statistics";
import { Routes, Route } from 'react-router-dom';
function App() {
return (
}/>
} />
}/>
} />
);
}
export default App;Обновите App.css, чтобы главный контейнер использовал flex:
body {
margin: 0;
padding: 0;
}
.App {
display: flex;
}
main {
padding: 10px;
}7. Примеры страниц
Добавьте простые компоненты в папку Pages:
// Home.js
export default function Home() {
return (
Home
)
}То же для Explore, Statistics и Settings. После запуска приложения переходы по ссылкам в сайдбаре должны менять содержимое main.
8. Модификация ссылок: NavLink vs div
Если в Sidenav вы рендерили div-элементы, замените их на NavLink, чтобы получить ссылку и подсветку активного маршрута. Пример внутри map:
{navData.map(item => {
return
{item.icon}
{item.text}
})}Обратите внимание на prop to — он принимает относительный или абсолютный путь.
9. Доступность и ARIA
- Кнопке toggle добавьте aria-label и aria-expanded. Это помогает экранным читалкам.
- Убедитесь, что контраст текста и фона отвечает требованиям WCAG (контраст должен быть достаточным для чтения).
- Навигацию можно обернуть в элемент
10. Тестирование и критерии приёмки
Критерии приёмки:
- Сайдбар по умолчанию открыт при загрузке (open === true).
- По клику на кнопку сайдбар сворачивается/разворачивается, меняется иконка.
- Навигация меняет путь и отображаемую страницу при клике.
- Активный маршрут подсвечивается стилем.
- Сайдбар доступен с клавиатуры (tab, enter).
Минимальные тест-кейсы:
- Навигация: клик по каждой ссылке ведёт на соответствующую страницу.
- Коллапс: при клике на кнопку ширина изменяется, текст скрывается, иконка меняется.
- Accessibility: aria-атрибуты присутствуют и работают с экранными читалками.
11. Альтернативные подходы
- CSS-in-JS (styled-components / @emotion): если вы предпочитаете JS-стили, можно вынести стили в компоненты.
- Использовать Drawer из Material UI вместо самописного сайдбара — проще интегрируется с темами MUI.
- Для сложных приложений с ролями: генерируйте navData на основе прав пользователя.
12. Когда этот подход не подходит
- Если вам нужен overlay-дашборд на мобильных устройствах, лучше использовать MUI Drawer или адаптивный компонент, который перекрывает контент.
- Для очень больших проектов с динамической навигацией из бека стоит хранить конфигурацию на сервере и мапить её на UI.
13. Подсказки по производительности
- Не храните JSX-иконки внутри navData как результат выражений, если navData приходит из API. Лучше хранить ключ и мапить ключ в компонент иконки при рендере.
- Отдельные страницы загружайте лениво (React.lazy + Suspense), чтобы не тянуть весь код страниц при первом рендере.
14. Совместимость и миграция
- Для react-router-dom v6 используйте
и element={ } вместо . - Проверяйте API NavLink: для динамического активного класса используйте функцию className: className={({ isActive }) => isActive ? styles.active : styles.sideitem}
15. Рекомендации по UX
- Для маленьких экранов замените сайдбар на скрываемый Drawer.
- Показывайте подсказку (tooltip) при наведении на иконку в свернутом состоянии, чтобы пользователь видел название ссылки.
- Добавьте плавные переходы для ширины и видимости текста для лучшего ощущения.
16. Чеклист для ролей
Для разработчика:
- Установлены зависимости MUI и react-router-dom
- Создан navData и Sidenav
- Реализован коллапс и aria-атрибуты
- Добавлены тесты навигации
Для дизайнера:
- Проверен контраст иконок и текста
- Подтверждён поведение в свернутом и развёрнутом виде
Для QA:
- Пройдены тест-кейсы маршрутизации и клавиатурной навигации
- Проверено поведение на мобильных устройствах
17. Проблемы и отладка
- Иконки не отображаются: убедитесь, что вы установили @mui/icons-material и импортируете нужные компоненты.
- NavLink не подсвечивается: в v6 используйте className={({ isActive }) => isActive ? styles.active : styles.sideitem}.
- CSS-модули не работают: проверьте расширение файла .module.css и корректный импорт styles from ‘./sidenav.module.css’.
18. Пример готовой реализации (сводка файлов)
- src/lib/navData.js — массив объектов навигации с иконками
- src/Components/Sidenav.js — основной компонент сайдбара
- src/Components/sidenav.module.css — локальные стили
- src/Pages/* — простые компоненты страниц
- src/App.js и src/index.js — маршрутизация и обёртка BrowserRouter
Если нужно, вы можете клонировать репозиторий с готовым примером (поиск на GitHub по ключевым словам: react sidenav material-ui).
19. Итог
React делает создание коллапсируемого сайдбара простым: используйте массив данных для пунктов, NavLink для маршрутов, useState для управления состоянием «открыто/закрыто» и CSS Modules для локальных стилей. В продакшн-версии добавьте ARIA-атрибуты, ленивую загрузку страниц и адаптивность для мобильных устройств.
Важно: адаптируйте подход в зависимости от размеров проекта и требуемой гибкости — от простого самописного сайдбара до использования готовых компонентов, таких как Drawer из Material UI.
Краткое резюме
- Храните navData отдельно и мапьте на NavLink.
- Управляйте коллапсом через useState и переключатель.
- Используйте react-router-dom v6 API (Routes/Route/NavLink).
- Улучшайте UX подсказками и доступностью.
Примечания
Если вам нужен полный рабочий проект с настройками ESLint, Prettier и готовыми тестами, дайте знать — могу добавить пример конфигурации и шаблоны тестов.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone