Snackbar для всплывающих сообщений

Snackbar — это компонент библиотеки MUI (Material-UI), предназначенный для отображения кратких уведомлений пользователю. Он автоматически появляется и исчезает через заданное время, не блокируя взаимодействие с интерфейсом.

import Snackbar from '@mui/material/Snackbar';
import Button from '@mui/material/Button';
import React, { useState } from 'react';

function App() {
  const [open, setOpen] = useState(false);

  const handleClick = () => setOpen(true);
  const handleClose = (event, reason) => {
    if (reason === 'clickaway') return;
    setOpen(false);
  };

  return (
    <div>
      <Button variant="contained" onCl ick={handleClick}>
        Показать уведомление
      </Button>
      <Snackbar
        open={open}
        autoHideDuration={3000}
        onCl ose={handleClose}
        message="Это уведомление Snackbar"
      />
    </div>
  );
}
  • open — контролирует видимость уведомления.
  • autoHideDuration — время отображения в миллисекундах.
  • onClose — функция закрытия, вызываемая при завершении времени или при клике пользователя.
  • message — текст сообщения. Можно передавать как строку или React-элемент.

Пользовательские действия и кнопки

Snackbar поддерживает добавление действий через свойство action, позволяющее вставлять кнопки, ссылки или иконки для взаимодействия.

import IconButton from '@mui/material/IconButton';
import CloseIcon from '@mui/icons-material/Close';

<Snackbar
  open={open}
  autoHideDuration={6000}
  onCl ose={handleClose}
  message="Сообщение с кнопкой закрытия"
  action={
    <IconButton
      size="small"
      aria-label="close"
      color="inherit"
      onCl ick={handleClose}
    >
      <CloseIcon fontSize="small" />
    </IconButton>
  }
/>
  • IconButton часто используется для закрытия уведомлений.
  • Можно добавлять несколько элементов в action, комбинируя кнопки и ссылки.

Размещение и позиционирование

MUI позволяет управлять позицией Snackbar на экране с помощью свойства anchorOrigin:

<Snackbar
  anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
  open={open}
  message="Уведомление в правом верхнем углу"
/>
  • vertical: ‘top’ или ‘bottom’.
  • horizontal: ‘left’, ‘center’, ‘right’.
  • Можно создавать разные расположения для разных уведомлений в одном приложении.

Использование Transition для анимаций

Snackbar поддерживает кастомные анимации через свойство TransitionComponent. MUI предоставляет несколько предустановленных переходов, включая Slide, Fade и Grow.

import Slide from '@mui/material/Slide';

function SlideTransition(props) {
  return <Slide {...props} direction="up" />;
}

<Snackbar
  open={open}
  onCl ose={handleClose}
  TransitionComponent={SlideTransition}
  message="Сообщение с анимацией Slide"
/>
  • direction для Slide задаёт направление появления уведомления.
  • Можно создавать собственные компоненты перехода, если необходим уникальный эффект.

Интеграция с React Context для глобальных уведомлений

Для крупных приложений удобно создать глобальный провайдер уведомлений. Это позволяет вызывать Snackbar из любого компонента без передачи состояния через props.

import React, { createContext, useContext, useState } from 'react';
import Snackbar from '@mui/material/Snackbar';

const SnackbarContext = createContext();

export const useSnackbar = () => useContext(SnackbarContext);

export function SnackbarProvider({ children }) {
  const [snackbar, setSnackbar] = useState({ open: false, message: '' });

  const showSnackbar = (message) => setSnackbar({ open: true, message });
  const closeSnackbar = () => setSnackbar({ ...snackbar, open: false });

  return (
    <SnackbarContext.Provider value={{ showSnackbar }}>
      {children}
      <Snackbar
        open={snackbar.open}
        message={snackbar.message}
        autoHideDuration={3000}
        onCl ose={closeSnackbar}
      />
    </SnackbarContext.Provider>
  );
}
  • SnackbarProvider оборачивает всё приложение.
  • useSnackbar() позволяет вызвать уведомление из любого компонента через showSnackbar("Текст уведомления").

Множественные уведомления и очередь

Чтобы показывать несколько сообщений последовательно, используется очередь. Для этого создают массив уведомлений и отображают их по очереди:

const [queue, setQueue] = useState([]);
const [current, setCurrent] = useState(null);

const enqueueSnackbar = (message) => {
  setQueue(prev => [...prev, { key: new Date().getTime(), message }]);
};

useEffect(() => {
  if (!current && queue.length) {
    setCurrent(queue[0]);
    setQueue(prev => prev.slice(1));
  }
}, [queue, current]);

<Snackbar
  key={current?.key}
  open={!!current}
  message={current?.message}
  autoHideDuration={3000}
  onCl ose={() => setCurrent(null)}
/>
  • Каждое уведомление получает уникальный ключ.
  • queue хранит все сообщения, ожидающие показа.
  • После закрытия одного уведомления автоматически показывается следующее.

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

Snackbar полностью интегрируется с системой тем MUI, позволяя настраивать цвет, типографику и тени:

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

const theme = createTheme({
  components: {
    MuiSnackbar: {
      styleOverrides: {
        root: {
          backgroundColor: '#323232',
          color: '#ffffff',
          borderRadius: '8px',
        },
      },
    },
  },
});

<ThemeProvider theme={theme}>
  <Snackbar open={true} message="Стилизация через тему" />
</ThemeProvider>
  • styleOverrides позволяет менять стили всех Snackbar в приложении.
  • Можно задавать разные темы для разных частей интерфейса.

Snackbar в MUI — гибкий инструмент для уведомлений, поддерживающий кастомные действия, позиции, анимации и глобальное управление через Context. В сочетании с очередями и системой тем, он обеспечивает удобное и красивое взаимодействие с пользователем без необходимости ручного контроля отображения.