LoadingButton для асинхронных операций

LoadingButton — это компонент библиотеки MUI, который расширяет возможности стандартной кнопки Button, предоставляя встроенную поддержку отображения состояния загрузки. Он особенно полезен для асинхронных операций, таких как запросы к серверу, отправка форм или любые действия, требующие ожидания завершения процесса.


Подключение и базовая настройка

Для использования LoadingButton необходимо установить пакет @mui/lab, так как компонент находится в экспериментальной библиотеке MUI:

import * as React from 'react';
import LoadingButton from '@mui/lab/LoadingButton';
import SaveIcon from '@mui/icons-material/Save';

Базовый пример использования:

<LoadingButton
  loading={false}
  variant="contained"
  onCl ick={handleClick}
>
  Сохранить
</LoadingButton>

Ключевые свойства:

  • loading — булевое значение, определяющее, отображается ли индикатор загрузки.
  • loadingPosition — позиция индикатора (start, end, center).
  • startIcon / endIcon — иконки, которые отображаются вместе с текстом кнопки. При активном loading могут заменяться индикатором.
  • variant, color, size — стандартные свойства MUI Button, полностью сохраняются.

Управление состоянием загрузки

Состояние загрузки чаще всего связывается с асинхронной функцией через хук useState. Пример с имитацией запроса к серверу:

import React, { useState } from 'react';

function AsyncSaveButton() {
  const [loading, setLoading] = useState(false);

  const handleClick = async () => {
    setLoading(true);
    try {
      await new Promise((resolve) => setTimeout(resolve, 2000)); // имитация запроса
    } finally {
      setLoading(false);
    }
  };

  return (
    <LoadingButton
      loading={loading}
      variant="contained"
      onCl ick={handleClick}
    >
      Сохранить
    </LoadingButton>
  );
}

При нажатии на кнопку loading становится true, кнопка блокируется, а индикатор загрузки отображается автоматически.


Позиционирование индикатора

loadingPosition позволяет выбрать, где будет располагаться спиннер относительно текста или иконки. Доступные варианты:

  • start — слева от текста или иконки.
  • end — справа от текста или иконки.
  • center — поверх кнопки, скрывая текст.

Пример с иконкой:

<LoadingButton
  loading={loading}
  loadingPosition="start"
  startIcon={<SaveIcon />}
  variant="contained"
>
  Сохранить
</LoadingButton>

При loadingPosition="center" текст можно скрыть с помощью свойства children, или оставить для анимации появления:

<LoadingButton
  loading={loading}
  loadingPosition="center"
  variant="contained"
>
  Сохранение...
</LoadingButton>

Интеграция с формами

LoadingButton отлично сочетается с отправкой форм, где состояние кнопки зависит от результата валидации или асинхронного запроса:

function SubmitForm() {
  const [loading, setLoading] = useState(false);

  const handleSubmit = async (event) => {
    event.preventDefault();
    setLoading(true);
    try {
      const formData = new FormData(event.target);
      await fetch('/api/submit', {
        method: 'POST',
        body: formData,
      });
    } finally {
      setLoading(false);
    }
  };

  return (
    <form onSub mit={handleSubmit}>
      <input name="name" type="text" required />
      <LoadingButton
        type="submit"
        loading={loading}
        variant="contained"
      >
        Отправить
      </LoadingButton>
    </form>
  );
}

Такое использование предотвращает множественные отправки и визуально показывает пользователю, что процесс выполняется.


Стилизация и кастомизация

Компонент наследует все возможности MUI Button по кастомизации:

<LoadingButton
  loading={loading}
  variant="outlined"
  color="secondary"
  size="large"
  sx={{ borderRadius: 4, paddingX: 3 }}
>
  Сохранить
</LoadingButton>
  • sx позволяет применять любые системные стили MUI.
  • variant поддерживает text, contained, outlined.
  • color может быть стандартным (primary, secondary) или кастомным через тему.

Рекомендации при асинхронных операциях

  1. Длительные запросы — использовать loading обязательно, чтобы пользователь видел прогресс.
  2. Обработка ошибок — возвращать кнопку в исходное состояние при неудаче запроса.
  3. Блокировка повторного кликаLoadingButton автоматически блокирует кнопку при активном loading, предотвращая дублирование запросов.
  4. Совмещение с иконками — индикатор загрузки можно разместить рядом с иконкой, не скрывая визуально смысл кнопки.

Дополнительные возможности

  • disabled при загрузке — можно комбинировать с loading для дополнительной блокировки.
  • Анимация спиннера — встроенный индикатор плавно появляется и исчезает, поддерживая визуальную консистентность интерфейса.
  • Полная интеграция с MUI Theme — цвета и размеры индикатора автоматически подстраиваются под тему.

Использование LoadingButton позволяет создавать интуитивно понятные интерфейсы, где асинхронные процессы визуально отделены от обычного взаимодействия с кнопкой, повышая удобство и предотвращая ошибки пользователя.