Гид по технологиям

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

5 min read Frontend Обновлено 09 Jan 2026
Боковая навигация в React — Material UI
Боковая навигация в 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

Если вы используете 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) если навигация должна управляться из разных компонентов.

Мини-методология разработки компонента

  1. Разбейте задачу: UI (JSX + CSS), данные (navData), маршруты (react-router).
  2. Напишите «моковые» страницы для проверки маршрутов.
  3. Сделайте базовую верстку и подключите маршрутизацию.
  4. Добавьте интерактивность (useState для открытия/закрытия).
  5. Тестируйте поведение при разных размерах экрана и с клавиатурой.
  6. Добавьте 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 в развернутом состоянии

Вид панели навигации React в свернутом состоянии

Итог

Создание сворачиваемой боковой навигации в React — это сочетание трёх вещей: корректных данных навигации, управления состоянием компонента и аккуратной стилизации. Предложенная структура и примеры помогут быстро интегрировать такой компонент в существующее приложение и адаптировать его под ваши требования.

Важно: при переносе в крупный проект подумайте о тестировании и управлении состоянием на уровне приложения.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство