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>
);
}
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>
}
/>
MUI позволяет управлять позицией Snackbar на экране с помощью свойства anchorOrigin:
<Snackbar
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
open={open}
message="Уведомление в правом верхнем углу"
/>
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"
/>
Для крупных приложений удобно создать глобальный провайдер уведомлений. Это позволяет вызывать 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>
);
}
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)}
/>
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>
Snackbar в MUI — гибкий инструмент для уведомлений, поддерживающий кастомные действия, позиции, анимации и глобальное управление через Context. В сочетании с очередями и системой тем, он обеспечивает удобное и красивое взаимодействие с пользователем без необходимости ручного контроля отображения.