Reapop is a powerful, Redux-based notification system for React applications. It provides a flexible and scalable approach to managing notifications using Redux for state management, making it ideal for complex applications that need centralized notification handling. This guide walks through advanced usage of Reapop with React and Redux, including custom configurations, middleware integration, and complex notification patterns. This is part 36 of a series on using Reapop 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
- Redux and React-Redux installed and configured
- Basic knowledge of Redux (actions, reducers, store)
- Understanding of React hooks (useSelector, useDispatch)
- Familiarity with JavaScript/TypeScript
Installation
Install Reapop and Redux dependencies:
npm install reapop react-redux redux
Or with yarn:
yarn add reapop react-redux redux
Or with pnpm:
pnpm add reapop react-redux redux
After installation, your package.json should include:
{
"dependencies": {
"reapop": "^4.0.0",
"react-redux": "^8.0.0",
"redux": "^4.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
}
Project Setup
Set up Redux store with Reapop reducer. First, create the Redux store:
// src/store/index.js
import { createStore, combineReducers } from 'redux';
import { reducer as notificationsReducer } from 'reapop';
const rootReducer = combineReducers({
notifications: notificationsReducer
});
export const store = createStore(rootReducer);
Now set up the provider and notification system in your main entry file:
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import { store } from './store';
import { NotificationsSystem } from 'reapop';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
<NotificationsSystem />
</Provider>
</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 { useDispatch } from 'react-redux';
import { notify } from 'reapop';
function NotificationExample() {
const dispatch = useDispatch();
const showSuccess = () => {
dispatch(notify({
title: 'Success!',
message: 'Operation completed successfully.',
status: 'success',
dismissible: true,
dismissAfter: 3000
}));
};
const showError = () => {
dispatch(notify({
title: 'Error!',
message: 'Something went wrong.',
status: 'error',
dismissible: true,
dismissAfter: 5000
}));
};
const showWarning = () => {
dispatch(notify({
title: 'Warning!',
message: 'Please review your input.',
status: 'warning',
dismissible: true,
dismissAfter: 4000
}));
};
const showInfo = () => {
dispatch(notify({
title: 'Info',
message: 'Here is some information.',
status: 'info',
dismissible: true,
dismissAfter: 3000
}));
};
return (
<div style={{ padding: '20px' }}>
<h2>Notification Examples</h2>
<div style={{ display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
<button onClick={showSuccess}>Success</button>
<button onClick={showError}>Error</button>
<button onClick={showWarning}>Warning</button>
<button onClick={showInfo}>Info</button>
</div>
</div>
);
}
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
Reapop uses Redux for state management where:
- notify action: Creates a new notification
- dismissNotification action: Dismisses a specific notification
- dismissNotifications action: Dismisses all notifications
- NotificationsSystem: Component that renders all notifications
- Redux Store: Centralized state management for all notifications
Key concepts for advanced usage:
- Redux Integration: Notifications are managed through Redux store
-
Action Creators: Use
notifyaction creator to create notifications - Middleware: Can integrate with Redux middleware for async operations
- Custom Components: Customize notification appearance and behavior
- Positioning: Configure notification positions and stacking
Here's an example with custom configuration:
// src/store/index.js
import { createStore, combineReducers, applyMiddleware } from 'redux';
import { reducer as notificationsReducer, setUpNotifications } from 'reapop';
import thunk from 'redux-thunk';
// Configure notifications
setUpNotifications({
defaultProps: {
position: 'top-right',
dismissible: true,
dismissAfter: 5000
}
});
const rootReducer = combineReducers({
notifications: notificationsReducer
});
export const store = createStore(rootReducer, applyMiddleware(thunk));
Practical Example / Building Something Real
Let's build a comprehensive notification system with custom hooks, middleware integration, and advanced features:
// src/hooks/useNotifications.js
import { useCallback } from 'react';
import { useDispatch } from 'react-redux';
import { notify, dismissNotification } from 'reapop';
export const useNotifications = () => {
const dispatch = useDispatch();
const showSuccess = useCallback((title, message, options = {}) => {
return dispatch(notify({
title,
message,
status: 'success',
dismissible: true,
dismissAfter: 3000,
...options
}));
}, [dispatch]);
const showError = useCallback((title, message, options = {}) => {
return dispatch(notify({
title,
message,
status: 'error',
dismissible: true,
dismissAfter: 5000,
...options
}));
}, [dispatch]);
const showWarning = useCallback((title, message, options = {}) => {
return dispatch(notify({
title,
message,
status: 'warning',
dismissible: true,
dismissAfter: 4000,
...options
}));
}, [dispatch]);
const showInfo = useCallback((title, message, options = {}) => {
return dispatch(notify({
title,
message,
status: 'info',
dismissible: true,
dismissAfter: 3000,
...options
}));
}, [dispatch]);
const showLoading = useCallback((title, message) => {
return dispatch(notify({
title,
message,
status: 'loading',
dismissible: false,
dismissAfter: 0
}));
}, [dispatch]);
const dismiss = useCallback((notificationId) => {
dispatch(dismissNotification(notificationId));
}, [dispatch]);
return {
showSuccess,
showError,
showWarning,
showInfo,
showLoading,
dismiss
};
};
Now create an advanced notification system component:
// src/AdvancedNotificationSystem.jsx
import React, { useState } from 'react';
import { useNotifications } from './hooks/useNotifications';
import { useDispatch } from 'react-redux';
import { dismissNotifications } from 'reapop';
function AdvancedNotificationSystem() {
const { showSuccess, showError, showWarning, showInfo, showLoading, dismiss } = useNotifications();
const dispatch = useDispatch();
const [formData, setFormData] = useState({
title: '',
message: '',
status: 'success'
});
const handleInputChange = (e) => {
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
};
const handleSubmit = (e) => {
e.preventDefault();
if (!formData.title || !formData.message) {
showError('Validation Error', 'Please fill in all fields.');
return;
}
const options = {
position: 'top-right',
dismissible: true
};
switch (formData.status) {
case 'success':
showSuccess(formData.title, formData.message, options);
break;
case 'error':
showError(formData.title, formData.message, options);
break;
case 'warning':
showWarning(formData.title, formData.message, options);
break;
case 'info':
showInfo(formData.title, formData.message, options);
break;
default:
showInfo(formData.title, formData.message, options);
}
setFormData({ title: '', message: '', status: 'success' });
};
const simulateApiCall = async () => {
const loadingId = showLoading('Processing', 'Processing your request...');
try {
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 2000));
dismiss(loadingId);
showSuccess('Success', 'Operation completed successfully!');
} catch (error) {
dismiss(loadingId);
showError('Error', 'Failed to complete operation. Please try again.');
}
};
const showActionNotification = () => {
const notificationId = showWarning('Action Required', 'Do you want to proceed?', {
dismissAfter: 0,
buttons: [
{
name: 'Yes',
primary: true,
onClick: () => {
dismiss(notificationId);
showSuccess('Confirmed', 'Action confirmed.');
}
},
{
name: 'No',
onClick: () => {
dismiss(notificationId);
showInfo('Cancelled', 'Action cancelled.');
}
}
]
});
};
const clearAllNotifications = () => {
dispatch(dismissNotifications());
};
return (
<div style={{ padding: '20px', maxWidth: '600px', margin: '0 auto' }}>
<h1>Advanced Notification System</h1>
<form onSubmit={handleSubmit} style={{ marginBottom: '20px', padding: '20px', border: '1px solid #ddd', borderRadius: '8px' }}>
<div style={{ marginBottom: '16px' }}>
<label style={{ display: 'block', marginBottom: '4px', fontWeight: '500' }}>
Title *
</label>
<input
type="text"
name="title"
value={formData.title}
onChange={handleInputChange}
style={{
width: '100%',
padding: '8px',
border: '1px solid #ddd',
borderRadius: '4px',
boxSizing: 'border-box'
}}
required
/>
</div>
<div style={{ marginBottom: '16px' }}>
<label style={{ display: 'block', marginBottom: '4px', fontWeight: '500' }}>
Message *
</label>
<textarea
name="message"
value={formData.message}
onChange={handleInputChange}
rows={3}
style={{
width: '100%',
padding: '8px',
border: '1px solid #ddd',
borderRadius: '4px',
boxSizing: 'border-box',
resize: 'vertical'
}}
required
/>
</div>
<div style={{ marginBottom: '16px' }}>
<label style={{ display: 'block', marginBottom: '4px', fontWeight: '500' }}>
Status
</label>
<select
name="status"
value={formData.status}
onChange={handleInputChange}
style={{
width: '100%',
padding: '8px',
border: '1px solid #ddd',
borderRadius: '4px',
boxSizing: 'border-box'
}}
>
<option value="success">Success</option>
<option value="error">Error</option>
<option value="warning">Warning</option>
<option value="info">Info</option>
</select>
</div>
<button
type="submit"
style={{
width: '100%',
padding: '10px',
backgroundColor: '#007bff',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
fontSize: '16px'
}}
>
Show Notification
</button>
</form>
<div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
<button
onClick={simulateApiCall}
style={{
padding: '10px',
backgroundColor: '#28a745',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Simulate API Call
</button>
<button
onClick={showActionNotification}
style={{
padding: '10px',
backgroundColor: '#ffc107',
color: 'black',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Show Action Notification
</button>
<button
onClick={clearAllNotifications}
style={{
padding: '10px',
backgroundColor: '#dc3545',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Clear All Notifications
</button>
</div>
</div>
);
}
export default AdvancedNotificationSystem;
Update your App.jsx:
// src/App.jsx
import React from 'react';
import AdvancedNotificationSystem from './AdvancedNotificationSystem';
import './App.css';
function App() {
return (
<div className="App">
<AdvancedNotificationSystem />
</div>
);
}
export default App;
Update your store configuration for better setup:
// src/store/index.js
import { createStore, combineReducers, applyMiddleware } from 'redux';
import { reducer as notificationsReducer, setUpNotifications } from 'reapop';
import thunk from 'redux-thunk';
// Configure notifications
setUpNotifications({
defaultProps: {
position: 'top-right',
dismissible: true,
dismissAfter: 5000,
allowHTML: false
}
});
const rootReducer = combineReducers({
notifications: notificationsReducer
});
export const store = createStore(
rootReducer,
applyMiddleware(thunk)
);
Common Issues / Troubleshooting
Notifications not displaying: Ensure
NotificationsSystemis rendered in your app andProviderwraps your application with the Redux store.Redux store not configured: Make sure you've added the notifications reducer to your Redux store using
combineReducers.Actions not working: Ensure you're using
useDispatchfromreact-reduxto dispatch notification actions. Thenotifyaction creator must be imported fromreapop.Notifications not dismissing: Check the
dismissAfterproperty. Set it to a number (milliseconds) for auto-dismissal, or 0 for persistent notifications. Usedismissible: trueto allow manual dismissal.Custom styling not working: Reapop allows custom notification components. You can override the default notification component by configuring it in
setUpNotifications.Multiple notifications stacking: Reapop handles multiple notifications automatically. They will stack based on the position setting. Use
dismissNotifications()to clear all notifications at once.
Next Steps
Now that you have an advanced understanding of Reapop:
- Explore Redux middleware integration for async notifications
- Learn about custom notification components
- Implement notification persistence and storage
- Add notification queues and limits
- Integrate with Redux DevTools for debugging
- Learn about other notification libraries (notistack, react-toastify)
- Check the official repository: https://github.com/LouisBarranqueiro/reapop
- Look for part 37 of this series for more advanced topics
Summary
You've successfully integrated Reapop into your React application with Redux for advanced notification management. Reapop provides a scalable, Redux-based solution for displaying notifications with centralized state management and extensive customization options.
SEO Keywords
reapop
React Redux notifications
reapop tutorial
React notification system
reapop installation
React Redux toast
reapop example
React notification library
reapop setup
React Redux alerts
reapop customization
React notification hooks
reapop middleware
React notification state
reapop getting started
Top comments (0)