Notistack is a powerful, Material-UI-based notification library for React that provides a simple API for displaying snackbar notifications. It offers extensive customization options, queue management, and seamless integration with Material-UI themes. This guide walks through advanced usage of Notistack with React, including custom configurations, action buttons, and complex notification patterns. This is part 33 of a series on using Notistack with React.
Prerequisites
Before you begin, make sure you have:
- Node.js version 14.0 or higher installed
- npm, yarn, or pnpm package manager
- A React project (version 16.8 or higher) or create-react-app setup
- Material-UI (MUI) installed in your project
- Basic knowledge of React hooks (useState, useEffect, useCallback)
- Familiarity with Material-UI components
- Understanding of async/await and Promises
Installation
Install Notistack and Material-UI dependencies:
npm install notistack @mui/material @emotion/react @emotion/styled
Or with yarn:
yarn add notistack @mui/material @emotion/react @emotion/styled
Or with pnpm:
pnpm add notistack @mui/material @emotion/react @emotion/styled
After installation, your package.json should include:
{
"dependencies": {
"notistack": "^3.0.0",
"@mui/material": "^5.0.0",
"@emotion/react": "^11.0.0",
"@emotion/styled": "^11.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
}
Project Setup
Set up the SnackbarProvider in your main entry file:
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { SnackbarProvider } from 'notistack';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<SnackbarProvider maxSnack={3}>
<App />
</SnackbarProvider>
</React.StrictMode>
);
First Example / Basic Usage
Let's create a simple notification component. Create a new file src/NotificationExample.jsx:
// src/NotificationExample.jsx
import React from 'react';
import { useSnackbar } from 'notistack';
import Button from '@mui/material/Button';
import Stack from '@mui/material/Stack';
function NotificationExample() {
const { enqueueSnackbar } = useSnackbar();
const showSuccess = () => {
enqueueSnackbar('Operation completed successfully!', {
variant: 'success',
anchorOrigin: {
vertical: 'top',
horizontal: 'right'
}
});
};
const showError = () => {
enqueueSnackbar('Something went wrong!', {
variant: 'error',
anchorOrigin: {
vertical: 'top',
horizontal: 'right'
}
});
};
const showWarning = () => {
enqueueSnackbar('Please review your input.', {
variant: 'warning',
anchorOrigin: {
vertical: 'top',
horizontal: 'right'
}
});
};
const showInfo = () => {
enqueueSnackbar('Here is some information.', {
variant: 'info',
anchorOrigin: {
vertical: 'top',
horizontal: 'right'
}
});
};
return (
<Stack spacing={2} direction="row" sx={{ padding: 2 }}>
<Button variant="contained" color="success" onClick={showSuccess}>
Success
</Button>
<Button variant="contained" color="error" onClick={showError}>
Error
</Button>
<Button variant="contained" color="warning" onClick={showWarning}>
Warning
</Button>
<Button variant="contained" color="info" onClick={showInfo}>
Info
</Button>
</Stack>
);
}
export default NotificationExample;
Update your App.jsx:
// src/App.jsx
import React from 'react';
import NotificationExample from './NotificationExample';
import './App.css';
function App() {
return (
<div className="App">
<NotificationExample />
</div>
);
}
export default App;
Understanding the Basics
Notistack provides several key features:
- useSnackbar Hook: React hook for accessing notification functions
- enqueueSnackbar: Function to add notifications to the queue
- Variants: success, error, warning, info, default
- Positioning: Customizable anchor positions (top/bottom, left/right/center)
- Actions: Add action buttons to notifications
- Queue Management: Automatic queue handling with maxSnack limit
- Material-UI Integration: Seamless integration with MUI themes
Key concepts for advanced usage:
-
Custom Content: Use the
contentoption to render custom React components - Action Buttons: Add action buttons with callbacks
- Persistent Notifications: Notifications that don't auto-dismiss
- Queue Management: Control how many notifications show at once
- Custom Styling: Override default styles with Material-UI's sx prop
Here's an example with action buttons:
// src/ActionNotificationExample.jsx
import React from 'react';
import { useSnackbar } from 'notistack';
import Button from '@mui/material/Button';
import IconButton from '@mui/material/IconButton';
import CloseIcon from '@mui/icons-material/Close';
function ActionNotificationExample() {
const { enqueueSnackbar, closeSnackbar } = useSnackbar();
const showActionNotification = () => {
const action = (snackbarId) => (
<>
<Button
size="small"
onClick={() => {
alert('Action clicked!');
closeSnackbar(snackbarId);
}}
>
Undo
</Button>
<IconButton
size="small"
aria-label="close"
color="inherit"
onClick={() => closeSnackbar(snackbarId)}
>
<CloseIcon fontSize="small" />
</IconButton>
</>
);
enqueueSnackbar('Item deleted successfully', {
variant: 'success',
action,
anchorOrigin: {
vertical: 'bottom',
horizontal: 'left'
}
});
};
const showPersistentNotification = () => {
enqueueSnackbar('This notification will not auto-dismiss', {
variant: 'info',
persist: true,
action: (snackbarId) => (
<IconButton
size="small"
aria-label="close"
color="inherit"
onClick={() => closeSnackbar(snackbarId)}
>
<CloseIcon fontSize="small" />
</IconButton>
)
});
};
return (
<div style={{ padding: '20px' }}>
<Button variant="contained" onClick={showActionNotification}>
Show Action Notification
</Button>
<Button
variant="contained"
color="secondary"
onClick={showPersistentNotification}
sx={{ ml: 2 }}
>
Show Persistent Notification
</Button>
</div>
);
}
export default ActionNotificationExample;
Practical Example / Building Something Real
Let's build a comprehensive notification system with custom hooks, error handling, and advanced features:
// src/hooks/useNotification.js
import { useCallback } from 'react';
import { useSnackbar } from 'notistack';
export const useNotification = () => {
const { enqueueSnackbar, closeSnackbar } = useSnackbar();
const showSuccess = useCallback((message, options = {}) => {
enqueueSnackbar(message, {
variant: 'success',
anchorOrigin: {
vertical: 'top',
horizontal: 'right'
},
autoHideDuration: 3000,
...options
});
}, [enqueueSnackbar]);
const showError = useCallback((message, options = {}) => {
enqueueSnackbar(message, {
variant: 'error',
anchorOrigin: {
vertical: 'top',
horizontal: 'right'
},
autoHideDuration: 5000,
...options
});
}, [enqueueSnackbar]);
const showWarning = useCallback((message, options = {}) => {
enqueueSnackbar(message, {
variant: 'warning',
anchorOrigin: {
vertical: 'top',
horizontal: 'right'
},
autoHideDuration: 4000,
...options
});
}, [enqueueSnackbar]);
const showInfo = useCallback((message, options = {}) => {
enqueueSnackbar(message, {
variant: 'info',
anchorOrigin: {
vertical: 'top',
horizontal: 'right'
},
autoHideDuration: 3000,
...options
});
}, [enqueueSnackbar]);
const showLoading = useCallback((message) => {
return enqueueSnackbar(message, {
variant: 'info',
persist: true,
anchorOrigin: {
vertical: 'top',
horizontal: 'right'
}
});
}, [enqueueSnackbar]);
return {
showSuccess,
showError,
showWarning,
showInfo,
showLoading,
closeSnackbar
};
};
Now create an advanced notification system component:
// src/AdvancedNotificationSystem.jsx
import React, { useState } from 'react';
import { useNotification } from './hooks/useNotification';
import Button from '@mui/material/Button';
import TextField from '@mui/material/TextField';
import Select from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';
import FormControl from '@mui/material/FormControl';
import InputLabel from '@mui/material/InputLabel';
import Box from '@mui/material/Box';
import Paper from '@mui/material/Paper';
import Typography from '@mui/material/Typography';
import Stack from '@mui/material/Stack';
import IconButton from '@mui/material/IconButton';
import CloseIcon from '@mui/icons-material/Close';
import { useSnackbar } from 'notistack';
function AdvancedNotificationSystem() {
const { showSuccess, showError, showWarning, showInfo, showLoading, closeSnackbar } = useNotification();
const { enqueueSnackbar } = useSnackbar();
const [formData, setFormData] = useState({
message: '',
variant: 'success',
duration: 3000
});
const handleInputChange = (e) => {
const { name, value } = e.target;
setFormData(prev => ({
...prev,
[name]: name === 'duration' ? parseInt(value) || 0 : value
}));
};
const handleSubmit = (e) => {
e.preventDefault();
if (!formData.message) {
showError('Please enter a message.');
return;
}
const options = {
autoHideDuration: formData.duration || undefined,
anchorOrigin: {
vertical: 'top',
horizontal: 'right'
}
};
switch (formData.variant) {
case 'success':
showSuccess(formData.message, options);
break;
case 'error':
showError(formData.message, options);
break;
case 'warning':
showWarning(formData.message, options);
break;
case 'info':
showInfo(formData.message, options);
break;
default:
showInfo(formData.message, options);
}
setFormData({ message: '', variant: 'success', duration: 3000 });
};
const simulateApiCall = async () => {
const loadingId = showLoading('Processing your request...');
try {
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 2000));
closeSnackbar(loadingId);
showSuccess('Operation completed successfully!');
} catch (error) {
closeSnackbar(loadingId);
showError('Failed to complete operation. Please try again.');
}
};
const showCustomContent = () => {
enqueueSnackbar('Custom notification with React component', {
variant: 'info',
content: (key, message) => (
<Paper
key={key}
elevation={3}
sx={{
p: 2,
backgroundColor: '#1976d2',
color: 'white',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
minWidth: 300
}}
>
<Typography variant="body1">{message}</Typography>
<IconButton
size="small"
aria-label="close"
sx={{ color: 'white' }}
onClick={() => closeSnackbar(key)}
>
<CloseIcon fontSize="small" />
</IconButton>
</Paper>
),
anchorOrigin: {
vertical: 'top',
horizontal: 'right'
}
});
};
const showActionNotification = () => {
enqueueSnackbar('Item will be deleted', {
variant: 'warning',
action: (snackbarId) => (
<Stack direction="row" spacing={1}>
<Button
size="small"
color="inherit"
onClick={() => {
showSuccess('Action cancelled');
closeSnackbar(snackbarId);
}}
>
Undo
</Button>
<IconButton
size="small"
aria-label="close"
color="inherit"
onClick={() => closeSnackbar(snackbarId)}
>
<CloseIcon fontSize="small" />
</IconButton>
</Stack>
),
anchorOrigin: {
vertical: 'bottom',
horizontal: 'left'
}
});
};
return (
<Box sx={{ padding: 3, maxWidth: 600, margin: '0 auto' }}>
<Typography variant="h4" gutterBottom>
Advanced Notification System
</Typography>
<Paper elevation={2} sx={{ p: 3, mb: 3 }}>
<form onSubmit={handleSubmit}>
<Stack spacing={2}>
<TextField
label="Message"
name="message"
value={formData.message}
onChange={handleInputChange}
fullWidth
required
/>
<FormControl fullWidth>
<InputLabel>Variant</InputLabel>
<Select
name="variant"
value={formData.variant}
onChange={handleInputChange}
label="Variant"
>
<MenuItem value="success">Success</MenuItem>
<MenuItem value="error">Error</MenuItem>
<MenuItem value="warning">Warning</MenuItem>
<MenuItem value="info">Info</MenuItem>
</Select>
</FormControl>
<TextField
label="Duration (ms)"
name="duration"
type="number"
value={formData.duration}
onChange={handleInputChange}
fullWidth
helperText="0 for persistent notification"
/>
<Button type="submit" variant="contained" fullWidth>
Show Notification
</Button>
</Stack>
</form>
</Paper>
<Stack spacing={2}>
<Button
variant="outlined"
onClick={simulateApiCall}
fullWidth
>
Simulate API Call
</Button>
<Button
variant="outlined"
color="secondary"
onClick={showCustomContent}
fullWidth
>
Show Custom Content
</Button>
<Button
variant="outlined"
color="warning"
onClick={showActionNotification}
fullWidth
>
Show Action Notification
</Button>
</Stack>
</Box>
);
}
export default AdvancedNotificationSystem;
Update your App.jsx:
// src/App.jsx
import React from 'react';
import { SnackbarProvider } from 'notistack';
import AdvancedNotificationSystem from './AdvancedNotificationSystem';
import './App.css';
function App() {
return (
<SnackbarProvider
maxSnack={3}
anchorOrigin={{
vertical: 'top',
horizontal: 'right'
}}
>
<div className="App">
<AdvancedNotificationSystem />
</div>
</SnackbarProvider>
);
}
export default App;
Common Issues / Troubleshooting
Notifications not displaying: Ensure
SnackbarProviderwraps your app at the root level. The provider must be a parent of components usinguseSnackbar.Material-UI theme not applied: Notistack uses Material-UI components, so make sure you have a
ThemeProviderwrapping your app if you're using custom themes.Action buttons not working: Make sure action functions receive the
snackbarIdparameter and usecloseSnackbar(snackbarId)to close the notification.Notifications stacking incorrectly: Use the
maxSnackprop onSnackbarProviderto control how many notifications show at once. AdjustanchorOriginfor positioning.Custom content not rendering: When using the
contentoption, the function receives(key, message)parameters. Return a valid React element.Persistent notifications: Set
persist: truein options to prevent auto-dismissal. Always provide a close button for persistent notifications.
Next Steps
Now that you have an advanced understanding of Notistack:
- Explore Material-UI theme customization for notifications
- Learn about notification queues and limits
- Implement notification persistence and storage
- Add sound effects or other interactive features
- Integrate with React Context for global notification management
- Learn about other notification libraries (react-toastify, react-notifications-component)
- Check the official documentation: https://iamhosseindhv.com/notistack
- Look for part 34 of this series for more advanced topics
Summary
You've successfully integrated Notistack into your React application with advanced features including custom hooks, action buttons, custom content, and async operation handling. Notistack provides a powerful, Material-UI-based solution for displaying snackbar notifications with extensive customization options.
SEO Keywords
notistack
React Material-UI notifications
notistack tutorial
React snackbar library
notistack installation
React toast notifications
notistack example
React notification system
notistack setup
React Material-UI snackbar
notistack hooks
React notification queue
notistack customization
React notification library
notistack getting started

Top comments (0)