DEV Community

Cover image for Creating a React Alert Component with Custom Hooks and Context
Mayank vishwakarma
Mayank vishwakarma

Posted on • Edited on

Creating a React Alert Component with Custom Hooks and Context

Discover how to use custom hooks and context to create an Alert Provider in a React application. This real-time example shows you how to easily show alerts across your application by managing them centrally.

Creating an Alert Provider in React Using Context and Custom Hooks

In any web application, providing feedback to users is crucial for a good user experience. One common way to provide feedback is through alerts, which notify users about important information or actions. In this blog post, we’ll explore how to create an Alert Provider in a React application using Context and custom hooks. This Alert Provider will allow us to show alerts anywhere in our application with ease.

Setting Up the Project

First, let's set up a new React project using Create React App:

npm init @vitejs/app alert-provider-demo --template react
cd alert-provider-demo
Enter fullscreen mode Exit fullscreen mode

Next, install the Bootstrap package for styling our alerts:

npm install react-bootstrap bootstrap
Enter fullscreen mode Exit fullscreen mode

Creating the Alert Context

We’ll start by defining our Alert Context and Alert Provider.

Create a new file named AlertContext.tsx in the src/context folder:

import React, { ReactNode, createContext, useEffect, useState } from 'react';
import Alert from 'react-bootstrap/Alert';
import 'bootstrap/dist/css/bootstrap.min.css';

type AlertType = 'Success' | 'Error' | 'Warning';

type Alert = {
  type: AlertType;
  message: string;
};

type AlertContext = {
  showAlert: (type: AlertType, message: string) => void;
};

type AlertContextProvider = {
  children: ReactNode;
};

// Create a new context for the Alert
export const AlertContext = createContext<AlertContext>({
  showAlert: () => {},
});

export const AlertProvider: React.FC<AlertContextProvider> = ({ children }) => {
  const [alertMessage, setAlertMessage] = useState<Alert[]>([]);

  // Function to hide an alert based on its index
  const hideAlert = (index: number) => {
    setAlertMessage((prev) => prev.filter((_, i) => i != index));
  };

  // UseEffect hook to remove the first alert message after 3 seconds
  useEffect(() => {
    const interval = setInterval(() => {
      setAlertMessage((prevItems) => {
        if (prevItems.length > 0) {
          return prevItems.filter((_, i) => i != 0);
        }
        clearInterval(interval);
        return prevItems;
      });
    }, 3 * 1000);
    return () => clearInterval(interval);
  }, []);

  // Context value containing the showAlert function
  const contextValue: AlertContext = {
    showAlert: (type, message) => {
      const alertMessage: Alert = {
        type,
        message,
      };
      setAlertMessage((prev) => [...prev, alertMessage]);
    },
  };

  return (
    <AlertContext.Provider value={contextValue}>
      <div
        style={{
          position: 'absolute',
          width: '100%',
          paddingTop: 10,
        }}
      >
        {alertMessage.map((alert, index) => (
          <Alert
            key={index}
            style={{ margin: 0, width: '100%' }}
            variant={alert.type.toLowerCase()}
            onClose={() => hideAlert(index)}
            dismissible
          >
            <div>{alert.message}</div>
          </Alert>
        ))}
      </div>
      {children}
    </AlertContext.Provider>
  );
};
Enter fullscreen mode Exit fullscreen mode

Create a new file named useAlert.ts in the src/hooks folder.

import { useContext } from "react";
import { AlertContext } from "../context/AlertProvider";

export const useAlert = ()=>{
  const context = useContext(AlertContext);
    if (!context) {
      throw new Error("useAlert must be used within a AlertProvider");
    }
    return context;
}
Enter fullscreen mode Exit fullscreen mode

Using the Alert Provider

Now, let’s use our AlertProvider in the main.tsx file:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';
import './index.css';
import { AlertProvider } from './context/AlertProvider.tsx';

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

Using the Custom Hook to Show Alerts

In any component where you want to show an alert, you can use the useAlert custom hook:

import React from 'react';
import { useAlert } from './hooks/useAlert';

function App() {
  const { showAlert } = useAlert();

  const handleClick = () => {
    showAlert('Success', 'This is a success message!');
  };

  return (
    <div>
      <button onClick={handleClick}>Show Alert</button>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Conclusion

This article demonstrated how to use Context and custom hooks to construct an Alert Provider in a React application. This solution enables you to manage alerts in a centralized manner, making it simple to show alerts throughout your application. Vite’s quick development environment improves your workflow and makes React programming even more efficient.

Top comments (2)

Collapse
 
denusklo profile image
denusklo

last part of the code should be import { useAlert } from './hooks/useAlert'; instead of import { useAlert } from './context/AlertProvider';

Collapse
 
mayankvishwakarmadev profile image
Mayank vishwakarma

Hey @denusklo,
Thank you for the suggestion!
I think there's a typo; I'll correct it.