DEV Community

James Parker
James Parker

Posted on

Building Notification Systems with react-notifications-component in React

react-notifications-component is a powerful React library for displaying toast notifications and alerts in your application. It provides a flexible notification system with customizable animations, positioning, and styling options. This guide walks through setting up and creating notification systems using react-notifications-component with React, from installation to a working implementation. This is part 32 of a series on using react-notifications-component 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
  • Basic knowledge of React hooks (useState, useEffect, useCallback)
  • Familiarity with JavaScript/TypeScript
  • Understanding of CSS for styling

Installation

Install react-notifications-component and its dependencies:

npm install react-notifications-component
Enter fullscreen mode Exit fullscreen mode

Or with yarn:

yarn add react-notifications-component
Enter fullscreen mode Exit fullscreen mode

Or with pnpm:

pnpm add react-notifications-component
Enter fullscreen mode Exit fullscreen mode

After installation, your package.json should include:

{
  "dependencies": {
    "react-notifications-component": "^4.0.0",
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

Project Setup

Set up the notification container in your main entry file:

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import ReactNotification from 'react-notifications-component';
import 'react-notifications-component/dist/theme.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
    <ReactNotification />
  </React.StrictMode>
);
Enter fullscreen mode Exit fullscreen mode

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 { store } from 'react-notifications-component';

function NotificationExample() {
  const showSuccessNotification = () => {
    store.addNotification({
      title: 'Success!',
      message: 'Operation completed successfully.',
      type: 'success',
      insert: 'top',
      container: 'top-right',
      animationIn: ['animate__animated', 'animate__fadeIn'],
      animationOut: ['animate__animated', 'animate__fadeOut'],
      dismiss: {
        duration: 3000,
        onScreen: true
      }
    });
  };

  const showErrorNotification = () => {
    store.addNotification({
      title: 'Error!',
      message: 'Something went wrong.',
      type: 'danger',
      insert: 'top',
      container: 'top-right',
      animationIn: ['animate__animated', 'animate__fadeIn'],
      animationOut: ['animate__animated', 'animate__fadeOut'],
      dismiss: {
        duration: 5000,
        onScreen: true
      }
    });
  };

  const showWarningNotification = () => {
    store.addNotification({
      title: 'Warning!',
      message: 'Please review your input.',
      type: 'warning',
      insert: 'top',
      container: 'top-right',
      animationIn: ['animate__animated', 'animate__fadeIn'],
      animationOut: ['animate__animated', 'animate__fadeOut'],
      dismiss: {
        duration: 4000,
        onScreen: true
      }
    });
  };

  const showInfoNotification = () => {
    store.addNotification({
      title: 'Info',
      message: 'Here is some information.',
      type: 'info',
      insert: 'top',
      container: 'top-right',
      animationIn: ['animate__animated', 'animate__fadeIn'],
      animationOut: ['animate__animated', 'animate__fadeOut'],
      dismiss: {
        duration: 3000,
        onScreen: true
      }
    });
  };

  return (
    <div style={{ padding: '20px' }}>
      <h2>Notification Examples</h2>
      <div style={{ display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
        <button onClick={showSuccessNotification}>Success</button>
        <button onClick={showErrorNotification}>Error</button>
        <button onClick={showWarningNotification}>Warning</button>
        <button onClick={showInfoNotification}>Info</button>
      </div>
    </div>
  );
}

export default NotificationExample;
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

Understanding the Basics

react-notifications-component uses a store-based API where:

  • store: Global notification store that manages all notifications
  • addNotification: Method to add a new notification
  • removeNotification: Method to remove a notification by ID
  • Container positions: top-left, top-right, top-center, bottom-left, bottom-right, bottom-center
  • Notification types: success, danger, warning, info, default
  • Animations: Uses animate.css classes for animations

Key concepts:

  • Store API: Notifications are managed through a global store
  • Positioning: Notifications can be positioned in different corners
  • Animations: Custom animations using CSS classes
  • Dismissal: Automatic or manual dismissal with callbacks
  • Customization: Extensive styling and content customization options

Here's an example with custom styling and actions:

// src/CustomNotificationExample.jsx
import React from 'react';
import { store } from 'react-notifications-component';

function CustomNotificationExample() {
  const showCustomNotification = () => {
    const notificationId = store.addNotification({
      title: 'Custom Notification',
      message: 'This is a custom styled notification with actions.',
      type: 'info',
      insert: 'top',
      container: 'top-right',
      animationIn: ['animate__animated', 'animate__fadeIn'],
      animationOut: ['animate__animated', 'animate__fadeOut'],
      dismiss: {
        duration: 0, // Don't auto-dismiss
        onScreen: true,
        showIcon: true
      },
      content: (
        <div style={{ padding: '10px' }}>
          <strong>Custom Content</strong>
          <p>You can add any React component here.</p>
          <button
            onClick={() => store.removeNotification(notificationId)}
            style={{
              padding: '5px 10px',
              backgroundColor: '#007bff',
              color: 'white',
              border: 'none',
              borderRadius: '4px',
              cursor: 'pointer',
              marginTop: '10px'
            }}
          >
            Dismiss
          </button>
        </div>
      )
    });
  };

  const showActionNotification = () => {
    store.addNotification({
      title: 'Action Required',
      message: 'Do you want to proceed?',
      type: 'warning',
      insert: 'top',
      container: 'top-center',
      animationIn: ['animate__animated', 'animate__slideInDown'],
      animationOut: ['animate__animated', 'animate__slideOutUp'],
      dismiss: {
        duration: 0,
        onScreen: true
      },
      actions: [
        {
          name: 'Yes',
          onClick: () => {
            store.addNotification({
              title: 'Confirmed!',
              message: 'Action confirmed.',
              type: 'success',
              insert: 'top',
              container: 'top-right',
              dismiss: { duration: 2000 }
            });
          },
          style: { backgroundColor: '#28a745', color: 'white' }
        },
        {
          name: 'No',
          onClick: () => {
            store.addNotification({
              title: 'Cancelled',
              message: 'Action cancelled.',
              type: 'info',
              insert: 'top',
              container: 'top-right',
              dismiss: { duration: 2000 }
            });
          },
          style: { backgroundColor: '#dc3545', color: 'white' }
        }
      ]
    });
  };

  return (
    <div style={{ padding: '20px' }}>
      <h2>Custom Notifications</h2>
      <div style={{ display: 'flex', gap: '10px' }}>
        <button onClick={showCustomNotification}>Custom Content</button>
        <button onClick={showActionNotification}>Action Buttons</button>
      </div>
    </div>
  );
}

export default CustomNotificationExample;
Enter fullscreen mode Exit fullscreen mode

Practical Example / Building Something Real

Let's build a comprehensive notification system with a custom hook and different notification types:

// src/hooks/useNotification.js
import { useCallback } from 'react';
import { store } from 'react-notifications-component';

export const useNotification = () => {
  const showSuccess = useCallback((title, message, options = {}) => {
    store.addNotification({
      title,
      message,
      type: 'success',
      insert: 'top',
      container: 'top-right',
      animationIn: ['animate__animated', 'animate__fadeIn'],
      animationOut: ['animate__animated', 'animate__fadeOut'],
      dismiss: {
        duration: 3000,
        onScreen: true
      },
      ...options
    });
  }, []);

  const showError = useCallback((title, message, options = {}) => {
    store.addNotification({
      title,
      message,
      type: 'danger',
      insert: 'top',
      container: 'top-right',
      animationIn: ['animate__animated', 'animate__fadeIn'],
      animationOut: ['animate__animated', 'animate__fadeOut'],
      dismiss: {
        duration: 5000,
        onScreen: true
      },
      ...options
    });
  }, []);

  const showWarning = useCallback((title, message, options = {}) => {
    store.addNotification({
      title,
      message,
      type: 'warning',
      insert: 'top',
      container: 'top-right',
      animationIn: ['animate__animated', 'animate__fadeIn'],
      animationOut: ['animate__animated', 'animate__fadeOut'],
      dismiss: {
        duration: 4000,
        onScreen: true
      },
      ...options
    });
  }, []);

  const showInfo = useCallback((title, message, options = {}) => {
    store.addNotification({
      title,
      message,
      type: 'info',
      insert: 'top',
      container: 'top-right',
      animationIn: ['animate__animated', 'animate__fadeIn'],
      animationOut: ['animate__animated', 'animate__fadeOut'],
      dismiss: {
        duration: 3000,
        onScreen: true
      },
      ...options
    });
  }, []);

  return {
    showSuccess,
    showError,
    showWarning,
    showInfo
  };
};
Enter fullscreen mode Exit fullscreen mode

Now create a component that uses the notification hook:

// src/NotificationSystem.jsx
import React, { useState } from 'react';
import { useNotification } from './hooks/useNotification';

function NotificationSystem() {
  const { showSuccess, showError, showWarning, showInfo } = useNotification();
  const [formData, setFormData] = useState({
    title: '',
    message: '',
    type: '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;
    }

    switch (formData.type) {
      case 'success':
        showSuccess(formData.title, formData.message);
        break;
      case 'error':
        showError(formData.title, formData.message);
        break;
      case 'warning':
        showWarning(formData.title, formData.message);
        break;
      case 'info':
        showInfo(formData.title, formData.message);
        break;
      default:
        showInfo(formData.title, formData.message);
    }

    setFormData({ title: '', message: '', type: 'success' });
  };

  const simulateApiCall = async () => {
    showInfo('Loading', 'Processing your request...', {
      dismiss: { duration: 0 }
    });

    try {
      // Simulate API call
      await new Promise(resolve => setTimeout(resolve, 2000));

      // Remove loading notification and show success
      showSuccess('Success', 'Operation completed successfully!');
    } catch (error) {
      showError('Error', 'Failed to complete operation. Please try again.');
    }
  };

  return (
    <div style={{ padding: '20px', maxWidth: '500px' }}>
      <h1>Notification System</h1>

      <form onSubmit={handleSubmit} style={{ marginBottom: '20px' }}>
        <div style={{ marginBottom: '16px' }}>
          <label style={{ display: 'block', marginBottom: '4px' }}>
            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' }}>
            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' }}>
            Type
          </label>
          <select
            name="type"
            value={formData.type}
            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={() => showSuccess('Quick Success', 'This is a quick success message!')}
          style={{
            padding: '10px',
            backgroundColor: '#28a745',
            color: 'white',
            border: 'none',
            borderRadius: '4px',
            cursor: 'pointer'
          }}
        >
          Quick Success
        </button>
        <button
          onClick={() => showError('Quick Error', 'This is a quick error message!')}
          style={{
            padding: '10px',
            backgroundColor: '#dc3545',
            color: 'white',
            border: 'none',
            borderRadius: '4px',
            cursor: 'pointer'
          }}
        >
          Quick Error
        </button>
        <button
          onClick={simulateApiCall}
          style={{
            padding: '10px',
            backgroundColor: '#ffc107',
            color: 'black',
            border: 'none',
            borderRadius: '4px',
            cursor: 'pointer'
          }}
        >
          Simulate API Call
        </button>
      </div>
    </div>
  );
}

export default NotificationSystem;
Enter fullscreen mode Exit fullscreen mode

Update your App.jsx:

// src/App.jsx
import React from 'react';
import NotificationSystem from './NotificationSystem';
import './App.css';

function App() {
  return (
    <div className="App">
      <NotificationSystem />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Common Issues / Troubleshooting

  1. Notifications not displaying: Ensure ReactNotification component is rendered in your app. It should be placed at the root level, typically in your main entry file.

  2. Animations not working: Make sure you have animate.css installed or use custom animation classes. The library uses CSS classes for animations.

  3. Notifications stacking incorrectly: Use the insert property to control stacking order ('top' or 'bottom'). Use container to set position.

  4. Custom content not rendering: When using the content property, make sure to return valid React elements. The content property accepts JSX.

  5. Notifications not dismissing: Check the dismiss configuration. Set duration: 0 to prevent auto-dismissal, or specify a duration in milliseconds.

  6. Multiple notification containers: You can have multiple ReactNotification components with different container IDs to show notifications in different positions simultaneously.

Next Steps

Now that you have an understanding of react-notifications-component:

  • Explore advanced customization options
  • Learn about custom animations and transitions
  • Implement notification queues and limits
  • Add sound effects or other interactive features
  • Integrate with React Context for global notification management
  • Learn about other notification libraries (notistack, react-toastify)
  • Check the official repository: https://github.com/teodosii/react-notifications-component
  • Look for part 33 of this series for more advanced topics

Summary

You've successfully set up react-notifications-component in your React application and created a notification system with custom hooks and different notification types. The library provides a flexible API for displaying toast notifications with extensive customization options.

SEO Keywords

react-notifications-component
React toast notifications
react-notifications-component tutorial
React notification system
react-notifications-component installation
React alert notifications
react-notifications-component example
React toast messages
react-notifications-component setup
React notification hooks
react-notifications-component customization
React notification library
react-notifications-component store
React toast library
react-notifications-component getting started

Top comments (0)