Шаблоны и паттерны

Библиотека MUI (Material-UI) предоставляет обширный набор готовых компонентов для построения интерфейсов на React, однако эффективное использование требует понимания архитектурных подходов и паттернов проектирования, применяемых при работе с компонентами. Важнейшие принципы включают разделение логики и презентации, композицию компонентов, переиспользуемость стилей и контроль состояния.


Компонентная композиция

MUI построен на концепции композиции компонентов, что позволяет объединять небольшие функциональные единицы в сложные интерфейсы. Принцип работы заключается в том, что каждый компонент имеет чётко определённый API, а его внутренние элементы могут быть легко заменены через пропсы slots или components.

Пример использования Button с кастомизацией:

import Button from '@mui/material/Button';
import { styled } from '@mui/material/styles';

const CustomButton = styled(Button)(({ theme }) => ({
  backgroundColor: theme.palette.primary.main,
  color: theme.palette.common.white,
  '&:hover': {
    backgroundColor: theme.palette.primary.dark,
  },
}));

<CustomButton variant="contained">Нажми меня</CustomButton>

Здесь реализован паттерн обёртки (Wrapper Pattern), позволяющий расширять функциональность стандартного компонента без модификации исходного кода.


Шаблон «Контейнер – Презентационный компонент»

Одним из ключевых паттернов в React и MUI является разделение на контейнеры (Container) и презентационные компоненты (Presentational Components):

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

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

// Контейнер
import React, { useState, useEffect } from 'react';
import UsersList from './UsersList';
import axios from 'axios';

function UsersContainer() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    axios.get('/api/users').then(res => setUsers(res.data));
  }, []);

  return <UsersList users={users} />;
}

export default UsersContainer;

// Презентационный компонент
import React from 'react';
import { List, ListItem, ListItemText } from '@mui/material';

function UsersList({ users }) {
  return (
    <List>
      {users.map(user => (
        <ListItem key={user.id}>
          <ListItemText primary={user.name} secondary={user.email} />
        </ListItem>
      ))}
    </List>
  );
}

export default UsersList;

Такой подход упрощает тестирование и повышает переиспользуемость компонентов.


Стилизация и паттерны темизации

MUI предлагает несколько способов стилизации:

  1. Styled API (@mui/system) – создание кастомных компонентов через функцию styled.
  2. SX-проп – inline-стили с поддержкой темы.
  3. Тема (Theme) + ThemeProvider – глобальная настройка цветов, отступов, шрифтов.

Пример использования темы с кастомными палитрами:

import { createTheme, ThemeProvider } from '@mui/material/styles';
import Button from '@mui/material/Button';

const theme = createTheme({
  palette: {
    primary: {
      main: '#1976d2',
    },
    secondary: {
      main: '#ff4081',
    },
  },
});

<ThemeProvider theme={theme}>
  <Button color="primary">Primary Button</Button>
</ThemeProvider>

Паттерн Theme Wrapper позволяет создавать набор стандартов интерфейса, которые можно применять ко всему приложению, обеспечивая единообразие визуального стиля.


Контроль состояния и паттерны управления

MUI компоненты часто требуют локального состояния для элементов управления (например, Select, Checkbox, Dialog). При этом полезно применять паттерны:

  • Controlled Component – полностью управляемый компонент через пропсы value и onChange.
  • Uncontrolled Component – компонент, который сам хранит внутреннее состояние, доступное через ref.

Пример контролируемого компонента Select:

import React, { useState } from 'react';
import { Select, MenuItem } from '@mui/material';

function LanguageSelect() {
  const [language, setLanguage] = useState('en');

  return (
    <Sel ect value={language} onCha nge={e => setLanguage(e.target.value)}>
      <MenuItem value="en">English</MenuItem>
      <MenuItem value="ru">Русский</MenuItem>
      <MenuItem value="es">Español</MenuItem>
    </Select>
  );
}

Использование контролируемых компонентов облегчает синхронизацию с глобальным состоянием через Redux, MobX или React Context.


Паттерн HOC (Higher-Order Component)

MUI поддерживает паттерн HOC, который позволяет расширять поведение компонентов без изменения их исходного кода. Например, withStyles позволяет добавлять стили:

import { withStyles } fr om '@mui/styles';
import Button from '@mui/material/Button';

const StyledButton = withStyles({
  root: {
    backgroundColor: '#4caf50',
    '&:hover': {
      backgroundColor: '#388e3c',
    },
  },
})(Button);

<StyledButton>Styled with HOC</StyledButton>

HOC особенно полезен для повторного применения логики или стилей к множеству компонентов.


Render Props и Slots

Для создания компонентов с гибкой структурой MUI активно использует render props и slots. Пример: компонент Autocomplete позволяет передавать кастомные элементы через renderInput или renderOption.

import Autocomplete from '@mui/material/Autocomplete';
import TextField from '@mui/material/TextField';

<Autocomplete
  options={['One', 'Two', 'Three']}
  renderInput={(params) => <TextField {...params} label="Choose" />}
  renderOption={(props, option) => <li {...props}>{option} option</li>}
/>

Этот подход поддерживает паттерн Inversion of Control, когда родительский компонент определяет структуру отображения дочерних элементов.


Паттерн Responsive Design

MUI предоставляет инструменты для адаптивной верстки через Grid и Box с поддержкой breakpoints:

import { Grid, Paper } from '@mui/material';

<Grid container spacing={2}>
  <Grid item xs={12} sm={6} md={4}>
    <Paper>Контент 1</Paper>
  </Grid>
  <Grid item xs={12} sm={6} md={4}>
    <Paper>Контент 2</Paper>
  </Grid>
</Grid>

Использование responsive breakpoints позволяет строить интерфейсы, которые корректно отображаются на разных устройствах без дублирования кода.


Итоговые ключевые паттерны

  1. Композиция компонентов – объединение маленьких компонентов в сложные структуры.
  2. Контейнер – презентационный компонент – разделение логики и представления.
  3. Theme Wrapper и Styled Components – стандартизация визуального оформления.
  4. Controlled / Uncontrolled Components – управление состоянием компонентов.
  5. HOC и Render Props – расширение функциональности и инверсии контроля.
  6. Responsive Grid и Breakpoints – адаптивный дизайн интерфейсов.

Эти паттерны позволяют создавать приложения на MUI, которые легко поддерживать, расширять и тестировать, обеспечивая при этом единый визуальный стиль и гибкость интерфейса.