Creating a React Alert Component with Custom Hooks and Context
Tags: react, frontend, developer, webdev
Published: 2024-03-30 12:24:43

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
```

Next, install the Bootstrap package for styling our alerts:
```
npm install react-bootstrap bootstrap
```

## 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>
  );
};
```

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;
}
```

## 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>
);
```

## 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;
```

## 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.