Интеграция с Formik

Основные принципы работы

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

Настройка окружения

Для начала необходимо установить пакеты:

npm install @mui/material @emotion/react @emotion/styled formik yup
  • @mui/material — основная библиотека компонентов.
  • @emotion/react и @emotion/styled — стилизация компонентов.
  • formik — управление состоянием формы.
  • yup — библиотека для валидации схем.

Основной подход

Formik управляет состоянием формы через объект values, ошибки через errors, и touched-поля через touched. Для корректной работы с MUI необходимо связать поля формы с этими объектами.

Пример базовой формы:

import { TextField, Button } from '@mui/material';
import { Formik, Form, Field } from 'formik';
import * as Yup from 'yup';

const validationSchema = Yup.object({
  email: Yup.string().email('Неверный формат email').required('Обязательное поле'),
  password: Yup.string().min(6, 'Минимум 6 символов').required('Обязательное поле')
});

function LoginForm() {
  return (
    <Formik
      initialValues={{ email: '', password: '' }}
      validationSchema={validationSchema}
      onSub mit={(values) => {
        console.log(values);
      }}
    >
      {({ errors, touched, handleChange, handleBlur, values }) => (
        <Form>
          <TextField
            name="email"
            label="Email"
            value={values.email}
            onCha nge={handleChange}
            onB lur={handleBlur}
            error={touched.email && Boolean(errors.email)}
            helperText={touched.email && errors.email}
            fullWidth
            margin="normal"
          />
          <TextField
            name="password"
            label="Пароль"
            type="password"
            value={values.password}
            onCha nge={handleChange}
            onB lur={handleBlur}
            error={touched.password && Boolean(errors.password)}
            helperText={touched.password && errors.password}
            fullWidth
            margin="normal"
          />
          <Button type="submit" variant="contained" color="primary">
            Войти
          </Button>
        </Form>
      )}
    </Formik>
  );
}

Использование Field и TextField

Formik предоставляет компонент Field, который можно обернуть в MUI TextField через проп as или используя render props. При этом важно корректно обрабатывать ошибки и touched-поля:

<Field name="username">
  {({ field, meta }) => (
    <TextField
      {...field}
      label="Имя пользователя"
      error={meta.touched && Boolean(meta.error)}
      helperText={meta.touched && meta.error}
      fullWidth
    />
  )}
</Field>

Такой подход позволяет полностью использовать возможности MUI по отображению ошибок и подсказок.

Обработка Checkbox и Radio

Для Checkbox и Radio компоненты MUI используют checked вместо value. В Formik это реализуется через setFieldValue:

import { Checkbox, FormControlLabel } from '@mui/material';
import { Field } from 'formik';

<Field name="subscribe">
  {({ field, form }) => (
    <FormControlLabel
      control={
        <Checkbox
          checked={field.value}
          onCha nge={() => form.setFieldValue(field.name, !field.value)}
        />
      }
      label="Подписаться на новости"
    />
  )}
</Field>

Sel ect и Autocomplete

Для Select MUI и Autocomplete Formik необходимо обрабатывать изменения через setFieldValue, так как стандартные события onChange отличаются от событий native-полей:

import { Select, MenuItem, FormControl, InputLabel } fr om '@mui/material';

<Field name="country">
  {({ field, form }) => (
    <FormControl fullWidth margin="normal">
      <InputLabel>Страна</InputLabel>
      <Sel ect
        value={field.value}
        onCha nge={(e) => form.setFieldValue(field.name, e.target.value)}
      >
        <MenuItem value="ru">Россия</MenuItem>
        <MenuItem value="us">США</MenuItem>
      </Select>
    </FormControl>
  )}
</Field>

Autocomplete требует аналогичной обработки:

import { Autocomplete, TextField } fr om '@mui/material';

<Autocomplete
  options={['Москва', 'Санкт-Петербург', 'Казань']}
  value={values.city}
  onCha nge={(_, newValue) => setFieldValue('city', newValue)}
  renderInput={(params) => (
    <TextField
      {...params}
      label="Город"
      error={touched.city && Boolean(errors.city)}
      helperText={touched.city && errors.city}
    />
  )}
/>

Валидация и Yup

Formik отлично интегрируется с Yup для построения схем валидации. Сложные структуры, массивы и вложенные объекты поддерживаются:

const schema = Yup.object({
  user: Yup.object({
    firstName: Yup.string().required('Обязательное поле'),
    lastName: Yup.string().required('Обязательное поле')
  }),
  hobbies: Yup.array().of(Yup.string().required('Введите значение'))
});

Formik автоматически подставляет ошибки и touched для вложенных полей при правильной структуре имени поля (user.firstName, hobbies[0]).

Стилизация и тема MUI

Для соответствия дизайну проекта можно использовать ThemeProvider и кастомные темы MUI:

import { createTheme, ThemeProvider } fr om '@mui/material/styles';

const theme = createTheme({
  palette: {
    primary: { main: '#1976d2' },
    secondary: { main: '#dc004e' }
  },
  components: {
    MuiTextField: {
      defaultProps: { variant: 'outlined' }
    }
  }
});

<ThemeProvider theme={theme}>
  <LoginForm />
</ThemeProvider>

Ключевые моменты интеграции

  • Использовать value и onChange Formik для стандартных полей TextField.
  • Для Checkbox, Radio, Select и Autocomplete применять setFieldValue.
  • Поддерживать отображение ошибок через error и helperText.
  • Валидация через Yup облегчает работу с сложными формами и вложенными объектами.
  • Рендеринг через Field или render props обеспечивает гибкость при стилизации MUI компонентов.

Эта интеграция позволяет строить формы, полностью соответствующие современным требованиям UX и поддерживающие строгую типизацию и валидацию данных.