Для интеграции 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 предоставляет компонент 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 определяет путь маршрута.Для текстовой навигации лучше использовать компонент
Link:
import { Link } from '@mui/material';
import { Link as RouterLink } from 'react-router-dom';
<Link component={RouterLink} to="/">
Главная
</Link>
Создание навигационного меню с 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' } });
Компонент 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
синхронизировано с текущим маршрутом, что обеспечивает автоматическое
выделение активной вкладки.
Для оптимизации загрузки страниц можно использовать
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 позволяет гибко
управлять переходами.