Библиотека MUI (Material-UI) предоставляет мощные инструменты для работы с компонентами интерфейса в React, включая систему уведомлений. Основной компонент для отображения временных уведомлений — это Snackbar. Для реализации очереди уведомлений, когда несколько уведомлений появляются одно за другим, MUI предлагает гибкие подходы через состояние и контекст приложения.
Snackbar используется для отображения кратких сообщений пользователю. Основные свойства:
open — булево значение, определяющее видимость
уведомления.message — текст уведомления.autoHideDuration — время в миллисекундах, через которое
уведомление автоматически скрывается.onClose — функция, вызываемая при закрытии
уведомления.action — дополнительные элементы интерфейса (например,
кнопка «Закрыть»).Пример базового использования:
import React, { useState } from 'react';
import Snackbar from '@mui/material/Snackbar';
import Button from '@mui/material/Button';
function SimpleSnackbar() {
const [open, setOpen] = useState(false);
const handleClick = () => setOpen(true);
const handleClose = (event, reason) => {
if (reason === 'clickaway') return;
setOpen(false);
};
return (
<>
<Button onCl ick={handleClick}>Показать уведомление</Button>
<Snackbar
open={open}
autoHideDuration={3000}
onCl ose={handleClose}
message="Пример уведомления"
/>
</>
);
}
Для корректного управления несколькими уведомлениями требуется
очередь. Стандартный Snackbar отображает
только одно уведомление за раз, поэтому нужно хранить массив уведомлений
и последовательно их показывать.
queue — массив объектов уведомлений:
{ message: string, key: number, variant?: 'success' | 'error' | 'info' }.current — текущее уведомление, отображаемое в
Snackbar.open — состояние видимости текущего уведомления.import React, { useState, useEffect } from 'react';
import Snackbar from '@mui/material/Snackbar';
import Button from '@mui/material/Button';
let keyCounter = 0;
function SnackbarQueue() {
const [queue, setQueue] = useState([]);
const [current, setCurrent] = useState(null);
const [open, setOpen] = useState(false);
const enqueueSnackbar = (message) => {
const key = keyCounter++;
setQueue((prev) => [...prev, { message, key }]);
};
useEffect(() => {
if (!current && queue.length > 0) {
setCurrent(queue[0]);
setQueue((prev) => prev.slice(1));
setOpen(true);
}
}, [queue, current]);
const handleClose = (event, reason) => {
if (reason === 'clickaway') return;
setOpen(false);
};
const handleExited = () => {
setCurrent(null);
};
return (
<>
<Button onCl ick={() => enqueueSnackbar('Первое уведомление')}>Добавить уведомление</Button>
<Snackbar
key={current?.key}
open={open}
message={current?.message}
autoHideDuration={3000}
onCl ose={handleClose}
onExi ted={handleExited}
/>
</>
);
}
Для отображения уведомлений с разными стилями (success,
error, info, warning) удобно
использовать Alert внутри Snackbar:
import Alert from '@mui/material/Alert';
<Snackbar
key={current?.key}
open={open}
autoHideDuration={3000}
onCl ose={handleClose}
onExi ted={handleExited}
>
<Alert onCl ose={handleClose} severity={current?.variant || 'info'}>
{current?.message}
</Alert>
</Snackbar>
Свойство severity задаёт цвет иконки и фон уведомления,
что повышает наглядность и удобство восприятия пользователем.
Чтобы использовать очередь уведомлений глобально, создают SnackbarContext:
import React, { createContext, useContext, useState } from 'react';
const SnackbarContext = createContext();
export const useSnackbar = () => useContext(SnackbarContext);
export function SnackbarProvider({ children }) {
const [queue, setQueue] = useState([]);
const [current, setCurrent] = useState(null);
const [open, setOpen] = useState(false);
const enqueueSnackbar = (message, variant = 'info') => {
const key = new Date().getTime() + Math.random();
setQueue((prev) => [...prev, { message, key, variant }]);
};
React.useEffect(() => {
if (!current && queue.length > 0) {
setCurrent(queue[0]);
setQueue((prev) => prev.slice(1));
setOpen(true);
}
}, [queue, current]);
const handleClose = (event, reason) => {
if (reason === 'clickaway') return;
setOpen(false);
};
const handleExited = () => setCurrent(null);
return (
<SnackbarContext.Provider value={{ enqueueSnackbar }}>
{children}
{current && (
<Snackbar
key={current.key}
open={open}
autoHideDuration={3000}
onCl ose={handleClose}
onExi ted={handleExited}
>
<Alert onCl ose={handleClose} severity={current.variant}>
{current.message}
</Alert>
</Snackbar>
)}
</SnackbarContext.Provider>
);
}
Теперь любой компонент в приложении может использовать
useSnackbar() для добавления уведомлений, не заботясь о
реализации очереди и отображении.
anchorOrigin можно выбрать место на экране:
{ vertical: 'top', horizontal: 'right' }.action можно добавить кнопки «Отмена», «Повторить»,
открытие модальных окон.TransitionComponent.Эта система позволяет создавать масштабируемую и управляемую очередь уведомлений с разнообразными стилями, действиями и гибкой интеграцией в приложение на React с MUI. Она легко расширяется для сложных интерфейсов, где важно последовательное и ненавязчивое информирование пользователя.