Боковая навигация в React с Material UI

О чём этот материал
Этот туториал шаг за шагом ведёт от создания проекта до рабочего компонента боковой навигации, который:
- отображает список ссылок с иконками Material UI;
- использует react-router-dom для маршрутизации;
- сворачивается и разворачивается по клику;
- оформлен с помощью CSS-модулей.
Важно: примеры кода ориентированы на React 17+/18+ и react-router-dom v6+. Если вы используете другую версию, проверьте совместимость в разделе Совместимость и миграция.
Требования и подготовка
Что нужно установить заранее:
- Node.js и npm (LTS рекомендуется);
- create-react-app (необязательно глобально — используется npx);
- базовые знания React и JSX.
Команды, которые мы используем:
npx create-react-app react-sidenav
npm install @mui/material @emotion/react @emotion/styled
npm install @mui/icons-material
npm install react-router-dom@latestПримечание: npm install react-router-dom@latest установит актуальную версию react-router-dom (v6+). В этой версии используется
Создание приложения React
Если у вас ещё нет проекта, создайте его командой выше. Для упрощения примера замените содержимое src/App.js на минимальный скелет:
import './App.css';
function App() {
return (
);
}
export default App;Это позволит нам добавлять компоненты постепенно.
Структура файлов
Рекомендуемая структура папок для примера:
- src/
- Components/
- Sidenav.js
- sidenav.module.css
- Pages/
- Home.js
- Explore.js
- Statistics.js
- Settings.js
- lib/
- navData.js
- App.js
- Index.js
- Components/
Если вы используете TypeScript, расширения файлов будут .tsx/.ts и синтаксис импорта типов потребуется адаптировать.
Данные навигации (navData)
Вместо ручного создания каждого элемента меню, соберите их в массив и итерируйте. Создайте файл src/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: "Главная",
link: "/"
},
{
id: 1,
icon: ,
text: "Исследовать",
link: "/explore"
},
{
id: 2,
icon: ,
text: "Статистика",
link: "/statistics"
},
{
id: 3,
icon: ,
text: "Настройки",
link: "/settings"
}
]Здесь мы локализовали текст ссылок на русский. Пути сделаны абсолютными (с ведущим “/“) — это упрощает работу NavLink и маршрутов.
Установка Material UI и иконок
Установите зависимости Material UI и пакет иконок:
npm install @mui/material @emotion/react @emotion/styled
npm install @mui/icons-materialПосле установки можно использовать иконки из пакета @mui/icons-material как JSX-элементы.
Компонент Sidenav
Создайте файл src/Components/Sidenav.js. Ниже — полный рабочий пример компонента с логикой сворачивания, NavLink и подключением CSS-модуля:
import React, { useState } from 'react';
import { NavLink } from 'react-router-dom';
import KeyboardDoubleArrowLeftIcon from '@mui/icons-material/KeyboardDoubleArrowLeft';
import KeyboardDoubleArrowRightIcon from '@mui/icons-material/KeyboardDoubleArrowRight';
import { navData } from '../lib/navData';
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}
);
})}
);
}Краткие пояснения:
- useState нужен для отслеживания состояния open (открыта/свернута);
- NavLink из react-router-dom создаёт ссылку и умеет возвращать active-состояние при совпадении пути;
- aria-label на кнопке улучшает доступность для вспомогательных технологий.
CSS-модуль
Создайте src/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-модули гарантируют уникальные имена классов и позволяют избежать конфликтов стилей в большом приложении.
Настройка маршрутов (react-router-dom)
В файле src/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 {
Routes,
Route,
} from "react-router-dom";
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";
function App() {
return (
} />
} />
} />
} />
);
}
export default App;И в App.css можно оставить простую раскладку:
body {
margin: 0;
padding: 0;
}
.App {
display: flex;
}
main {
padding: 10px;
}Примеры простых страниц
Создайте четыре файла в src/Pages: Home.js, Explore.js, Statistics.js, Settings.js. Пример Home.js:
export default function Home() {
return (
Главная
)
}Если вы перейдёте по пути /explore, увидите компонент Explore и т.д.
Типичные проблемы и их решения
- Ссылки NavLink не ведут туда: убедитесь, что пути в navData начинаются с “/“.
- Стили не применяются: проверьте, что файл импортирован как CSS-модуль (имя файла *.module.css) и импортируется как styles из ‘./sidenav.module.css’.
- Иконки не отображаются: убедитесь, что установлен @mui/icons-material и импорт иконок корректен.
- Неправильное поведение при вложенных путях: NavLink по умолчанию проверяет частичное совпадение; используйте prop end для строгого совпадения, например
.
Альтернативные подходы
- Использовать styled-components или Emotion вместо CSS-модулей для динамических стилей;
- Применить Tailwind CSS для утилитарной стилизации и меньшего объёма CSS;
- Управлять открытием панели через глобальный state (Redux, Zustand) если навигация должна управляться из разных компонентов.
Мини-методология разработки компонента
- Разбейте задачу: UI (JSX + CSS), данные (navData), маршруты (react-router).
- Напишите «моковые» страницы для проверки маршрутов.
- Сделайте базовую верстку и подключите маршрутизацию.
- Добавьте интерактивность (useState для открытия/закрытия).
- Тестируйте поведение при разных размерах экрана и с клавиатурой.
- Добавьте aria-атрибуты и проверку доступности.
Чек-лист для вывода в продакшн
- Пути в navData — корректные и ожидаемые;
- Навигация доступна с клавиатуры (Tab/Enter);
- aria-label и роли для элементов управления (кнопка открытия);
- Проверены поведенческие сценарии на мобильных устройствах;
- Локализация текстов (при необходимости) и корректная кодировка;
- Оптимизирован импорт иконок (tree-shaking);
- Тесты: unit для логики сворачивания и интеграционные для маршрутов.
Критерии приёмки
- Компонент отображается корректно в Chrome, Firefox и Safari;
- Ссылки переводят на соответствующие маршруты;
- Панель сворачивается/разворачивается без визуальных артефактов;
- При сворачивании текст ссылок скрывается, а иконки остаются доступными;
- Элементы управления доступны по клавиатуре.
Совместимость и миграция
- React Router: подход рассчитан на v6; если вы используете v5, синтаксис Route/Router отличается.
- Material UI: примеры используют MUI v5 (пакеты @mui/*). Для MUI v4 синтаксис и структура библиотек другие.
Безопасность и приватность
Компонент навигации не обрабатывает пользовательские данные и не хранит конфиденциальную информацию. При интеграции в приложение убедитесь, что маршруты защищены (авторизация) на уровне маршрутизатора и бэкенда.
Глоссарий (одной строкой)
- NavLink: компонент реактора для создания ссылок с активным состоянием;
- CSS-модуль: локально изолированный CSS-файл, импортируемый в компонент;
- useState: хук React для локального состояния во функциональном компоненте.


Итог
Создание сворачиваемой боковой навигации в React — это сочетание трёх вещей: корректных данных навигации, управления состоянием компонента и аккуратной стилизации. Предложенная структура и примеры помогут быстро интегрировать такой компонент в существующее приложение и адаптировать его под ваши требования.
Важно: при переносе в крупный проект подумайте о тестировании и управлении состоянием на уровне приложения.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone