MUI (Material-UI) предоставляет мощный набор компонентов для построения интерфейсов на JavaScript и React. Эффективная организация компонентов позволяет создавать масштабируемые, поддерживаемые и переиспользуемые интерфейсы. Основные принципы организации включают иерархию компонентов, разделение логики и презентации и использование тематических и стилизованных компонентов.
Компоненты в MUI можно разделить на три уровня:
Button, TextField,
Checkbox. Они редко содержат сложную логику и используются
как строительные блоки. Пример атомарного компонента с MUI:import Button from '@mui/material/Button';
function PrimaryButton({ label, onClick }) {
return (
<Button variant="contained" color="primary" onCl ick={onClick}>
{label}
</Button>
);
}
TextField и Button:import TextField from '@mui/material/TextField';
import Button from '@mui/material/Button';
import Box from '@mui/material/Box';
function SearchForm({ value, onChange, onSubmit }) {
return (
<Box component="form" onSub mit={onSubmit} display="flex" gap={1}>
<TextField value={value} onCha nge={onChange} placeholder="Поиск..." />
<Button type="submit" variant="contained">Найти</Button>
</Box>
);
}
import AppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
import Typography from '@mui/material/Typography';
import SearchForm from './SearchForm';
function Header() {
return (
<AppBar position="static">
<Toolbar>
<Typography variant="h6" sx={{ flexGrow: 1 }}>Мой сайт</Typography>
<SearchForm />
</Toolbar>
</AppBar>
);
}
MUI позволяет отделять логику работы компонента от его визуального представления, что повышает переиспользуемость. Обычно создаются два типа компонентов:
Пример разделения:
// Контейнер
function UserProfileContainer({ userId }) {
const [user, setUser] = React.useState(null);
React.useEffect(() => {
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(setUser);
}, [userId]);
if (!user) return null;
return <UserProfileCard user={user} />;
}
// Презентационный компонент
import Card from '@mui/material/Card';
import CardContent from '@mui/material/CardContent';
import Typography from '@mui/material/Typography';
function UserProfileCard({ user }) {
return (
<Card>
<CardContent>
<Typography variant="h5">{user.name}</Typography>
<Typography variant="body2">{user.email}</Typography>
</CardContent>
</Card>
);
}
MUI предлагает мощную систему стилизации через
sx-проп, styled API и
ThemeProvider. Это позволяет создавать единый
визуальный язык для приложения.
sx для кастомизации:<Box sx={{ display: 'flex', gap: 2, p: 2, bgcolor: 'background.paper' }}>
<Button variant="contained" color="secondary">Кнопка 1</Button>
<Button variant="outlined" color="primary">Кнопка 2</Button>
</Box>
import { createTheme, ThemeProvider } from '@mui/material/styles';
const theme = createTheme({
palette: {
primary: { main: '#1976d2' },
secondary: { main: '#dc004e' },
},
typography: {
h6: { fontWeight: 600 },
},
});
function App() {
return (
<ThemeProvider theme={theme}>
<Header />
<MainContent />
</ThemeProvider>
);
}
MUI поддерживает композицию компонентов через пропсы
children и HOC (Higher Order Components). Это облегчает
создание универсальных компонентов, которые можно
адаптировать под разные задачи.
function CardWrapper({ children, title }) {
return (
<Card sx={{ mb: 2 }}>
{title && <Typography variant="h6" sx={{ p: 2 }}>{title}</Typography>}
{children}
</Card>
);
}
// Использование
<CardWrapper title="Информация о пользователе">
<UserProfileCard user={user} />
</CardWrapper>
Для больших проектов структура может быть следующей:
/components
/atoms
Button.js
TextField.js
/molecules
SearchForm.js
/organisms
Header.js
/pages
HomePage.js
ProfilePage.js
Рекомендации:
Для управления состоянием интерфейса используют React
Context или глобальные стейты (Redux,
Zustand). MUI компоненты легко интегрируются с контекстом
для темизации, авторизации и
глобальных настроек интерфейса.
Пример контекста темы:
import { createContext, useContext, useState } from 'react';
const ThemeModeContext = createContext();
export function ThemeModeProvider({ children }) {
const [mode, setMode] = useState('light');
const toggleMode = () => setMode(prev => prev === 'light' ? 'dark' : 'light');
return (
<ThemeModeContext.Provider value={{ mode, toggleMode }}>
{children}
</ThemeModeContext.Provider>
);
}
export function useThemeMode() {
return useContext(ThemeModeContext);
}
Эти подходы формируют чистую архитектуру компонентов, делают код более читаемым и удобным для командной разработки, повышают скорость прототипирования и поддержку интерфейса.