React Router интеграция

Для интеграции React Router с MUI необходимо установить соответствующие зависимости:

npm install @mui/material @emotion/react @emotion/styled react-router-dom

После установки создается базовая структура приложения с использованием BrowserRouter из react-router-dom:

import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { Container } from '@mui/material';
import Home from './pages/Home';
import About from './pages/About';
import Navbar from './components/Navbar';

function App() {
  return (
    <BrowserRouter>
      <Navbar />
      <Container>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
        </Routes>
      </Container>
    </BrowserRouter>
  );
}

export default App;

Ключевой момент: BrowserRouter должен оборачивать все компоненты, которые используют маршрутизацию, чтобы обеспечить доступ к контексту маршрутов.


Навигация с использованием компонентов MUI

MUI предоставляет компонент Button и Link, которые можно интегрировать с react-router-dom через свойство component.

import { Button } from '@mui/material';
import { Link as RouterLink } from 'react-router-dom';

<Button component={RouterLink} to="/about" variant="contained" color="primary">
  Перейти на About
</Button>

Особенности:

  • component={RouterLink} заменяет стандартный HTML-тег <a> на компонент маршрутизатора.
  • Свойство to определяет путь маршрута.
  • Стили MUI сохраняются полностью.

Для текстовой навигации лучше использовать компонент Link:

import { Link } from '@mui/material';
import { Link as RouterLink } from 'react-router-dom';

<Link component={RouterLink} to="/">
  Главная
</Link>

Интеграция Drawer и AppBar

Создание навигационного меню с Drawer и AppBar является стандартной практикой в MUI. Для интеграции маршрутов Drawer использует ListItemButton с component={RouterLink}:

import React, { useState } from 'react';
import { AppBar, Toolbar, IconButton, Drawer, List, ListItemButton, ListItemText } from '@mui/material';
import MenuIcon from '@mui/icons-material/Menu';
import { Link as RouterLink } from 'react-router-dom';

function Navbar() {
  const [open, setOpen] = useState(false);

  return (
    <>
      <AppBar position="static">
        <Toolbar>
          <IconButton edge="start" color="inherit" onCl ick={() => setOpen(true)}>
            <MenuIcon />
          </IconButton>
        </Toolbar>
      </AppBar>
      <Drawer open={open} onCl ose={() => setOpen(false)}>
        <List>
          <ListItemButton component={RouterLink} to="/" onCl ick={() => setOpen(false)}>
            <ListItemText primary="Главная" />
          </ListItemButton>
          <ListItemButton component={RouterLink} to="/about" onCl ick={() => setOpen(false)}>
            <ListItemText primary="О нас" />
          </ListItemButton>
        </List>
      </Drawer>
    </>
  );
}

export default Navbar;

Ключевой момент: использование onCl ick={() => setOpen(false)} позволяет закрывать Drawer при выборе пункта меню, улучшая UX.


Активный маршрут и стилизация

Для отображения активного маршрута можно использовать хук useLocation:

import { useLocation } from 'react-router-dom';
import { ListItemButton, ListItemText } from '@mui/material';

function MenuItem({ to, label }) {
  const location = useLocation();
  const isActive = location.pathname === to;

  return (
    <ListItemButton
      component={RouterLink}
      to={to}
      selected={isActive} // MUI автоматически применяет стиль выделения
    >
      <ListItemText primary={label} />
    </ListItemButton>
  );
}

Примечание: свойство selected у MUI ListItemButton позволяет легко реализовать визуальное выделение активного маршрута без кастомного CSS.


Программная навигация

Для перехода между маршрутами в коде используется хук useNavigate:

import { useNavigate } from 'react-router-dom';
import { Button } from '@mui/material';

function Home() {
  const navigate = useNavigate();

  return (
    <Button variant="contained" onCl ick={() => navigate('/about')}>
      Перейти на About
    </Button>
  );
}

Особенности:

  • Позволяет выполнять переход по событию (например, после успешной формы).
  • Можно передавать состояние или параметры через объект:
navigate('/about', { state: { from: 'home' } });

Интеграция с MUI Tabs

Компонент Tabs можно использовать для переключения страниц:

import { Tabs, Tab } from '@mui/material';
import { useLocation, useNavigate } from 'react-router-dom';

function NavTabs() {
  const location = useLocation();
  const navigate = useNavigate();

  const handleChange = (event, newValue) => {
    navigate(newValue);
  };

  return (
    <Tabs value={location.pathname} onCha nge={handleChange}>
      <Tab label="Главная" value="/" />
      <Tab label="О нас" value="/about" />
    </Tabs>
  );
}

Ключевой момент: значение value в Tabs синхронизировано с текущим маршрутом, что обеспечивает автоматическое выделение активной вкладки.


Lazy Loading компонентов с React Router

Для оптимизации загрузки страниц можно использовать React.lazy и Suspense:

import React, { Suspense, lazy } from 'react';
import { Routes, Route } from 'react-router-dom';

const Home = lazy(() => import('./pages/Home'));
const About = lazy(() => import('./pages/About'));

function AppRoutes() {
  return (
    <Suspense fallback={<div>Загрузка...</div>}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Suspense>
  );
}

Особенности:

  • Подходит для больших проектов с множеством страниц.
  • Снижает первоначальный размер бандла и ускоряет загрузку.

Передача пропсов через маршруты

Состояние или данные можно передавать через state:

navigate('/about', { state: { userId: 42 } });

А для чтения используется хук useLocation:

import { useLocation } from 'react-router-dom';

function About() {
  const location = useLocation();
  const { userId } = location.state || {};

  return <div>Пользователь: {userId}</div>;
}

Обработка маршрутов с параметрами

React Router позволяет создавать динамические маршруты:

<Route path="/user/:id" element={<User />} />

В компоненте:

import { useParams } from 'react-router-dom';

function User() {
  const { id } = useParams();

  return <div>Профиль пользователя: {id}</div>;
}

Ключевой момент: комбинация useParams и MUI компонентов позволяет легко создавать страницы с динамическим контентом, сохраняя стилистику приложения.


Итоговая структура проекта

Пример структуры:

src/
├─ components/
│  └─ Navbar.jsx
├─ pages/
│  ├─ Home.jsx
│  └─ About.jsx
├─ App.jsx
└─ index.js

Рекомендации:

  • Использовать Container и Grid компоненты MUI для организации контента.
  • Для навигации применять комбинацию Link, Button и ListItemButton.
  • Программная навигация через useNavigate позволяет гибко управлять переходами.
  • Lazy Loading и динамические маршруты оптимизируют производительность и масштабируемость приложения.