# Creating a Reusable Snackbar Component in Next.js

Notifications and alerts are an essential part of user interaction in web applications. They inform users about successes, errors, and other significant events. Material-UI’s Snackbar component is a popular choice for displaying these brief messages. In this post, we’ll explore how to create a reusable Snackbar component in a Next.js application using React context and hooks.

## **Why Use a Context for Snackbar?**

In complex applications, you often need to trigger notifications from many different components. Passing down props or callbacks through multiple layers of components can get messy. A more elegant solution is to use a React context. This allows any component in your application to easily display a notification without prop drilling.

## **Setting Up the Snackbar Context**

First, we create a new context for the Snackbar in a separate file (`SnackbarContext.js`):

```javascript
import { createContext, useContext, useState, useCallback } from 'react';

export const SnackbarContext = createContext();

export const useSnackbar = () => useContext(SnackbarContext);

export const SnackbarProvider = ({ children }) => {
  const [snackPack, setSnackPack] = useState([]);

  const addSnackbar = useCallback((message, severity = 'info') => {
    setSnackPack((prev) => [...prev, { message, severity, key: new Date().getTime() }]);
  }, []);

  return (
    <SnackbarContext.Provider value={{ addSnackbar }}>
      {children}
      {/* Snackbar Component will be added here */}
    </SnackbarContext.Provider>
  );
};
```

This `SnackbarProvider` component will wrap our application, providing the `addSnackbar` function through context to any child component.

## **Creating the Reusable Snackbar Component**

Within the `SnackbarProvider`, we include the reusable Snackbar component that listens to the `snackPack` state:

```javascript
import { Alert, Snackbar } from '@mui/material';

// ... inside SnackbarProvider component

{snackPack.map((snack, index) => (
  <Snackbar
    key={snack.key}
    open
    autoHideDuration={6000}
    onClose={() => {
      setSnackPack((prev) => prev.filter((item) => item.key !== snack.key));
    }}
    anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
  >
    <Alert onClose={() => {
      setSnackPack((prev) => prev.filter((item) => item.key !== snack.key));
    }} severity={snack.severity} sx={{ width: '100%' }}>
      {snack.message}
    </Alert>
  </Snackbar>
))}
```

Each message in the `snackPack` array is displayed as a Snackbar. We use the `key` property to uniquely identify each message, which is helpful for dismissing messages correctly.

## **Integrating SnackbarProvider in Your Application**

In your Next.js `_app.js` file, wrap your application with the `SnackbarProvider`:

```javascript
import { SnackbarProvider } from '../path/to/SnackbarContext';

function MyApp({ Component, pageProps }) {
  return (
    <SnackbarProvider>
      <Component {...pageProps} />
    </SnackbarProvider>
  );
}

export default MyApp;
```

## **Using the useSnackbar Hook**

Anywhere in your application, you can now use the `useSnackbar` hook to trigger Snackbar messages:

```javascript
import { useSnackbar } from '../path/to/SnackbarContext';

const MyComponent = () => {
  const { addSnackbar } = useSnackbar();

  const handleAction = () => {
    addSnackbar('This action was successful!', 'success');
  };

  return (
    // Your component JSX
  );
};
```

## **Conclusion**

This approach simplifies the process of displaying notifications in a Next.js application. By using a context provider, we can avoid prop drilling and make our notification system more maintainable and elegant.

The reusable Snackbar component makes it easy to display consistent and attractive notifications across the entire application, enhancing the user experience.
