Toast notifications are small messages that appear on the screen to inform users about an action or event. When a user saves a form, deletes a record, or uploads a file, we may want to display a message for the action success, like “Saved successfully", or when in the case of an error, we may want to display a message like “Something went wrong”. A toast notification is the best solution for these cases. Toast notifications do not block the user from interacting with the application;, they can appear for a short period of time and then disappear automatically. In this blog, we can build a simple toast notification system using React.
1. Create a React Project
First, create a new React project with this.
npm create vite@latest react-toast -- --template react
cd react-toast
npm install
npm run dev
2. Create a Toast Component
Now, we can create the component for the toast. Create a new file called Toast.jsx. This component will render a toast notification message and also provide a close button. Here, we are adding three types of toasts – success, error, and info, with different styles. The message for the toast will be received as a prop to the component.
export default function Toast({ message, type, onClose }) {
const colors = {
success: "bg-green-100 text-green-800",
error: "bg-red-100 text-red-800",
info: "bg-blue-100 text-blue-800",
};
return (
<div
role="status"
className={`flex items-center justify-between gap-4 rounded-lg p-4 ${colors[type]}`}
>
<p>{message}</p>
<button onClick={onClose} aria-label="Close notification">
×
</button>
</div>
);
}3. Manage Toast Notifications with State
Now, we need a way to manage and display notifications from different parts of our application. So we can create a custom hook to handle this with the help of React state and functions. Create a new file called useToast.js.
import { useState } from "react";
export function useToast() {
const [toasts, setToasts] = useState([]);
const showToast = (message, type = "info") => {
const id = crypto.randomUUID();
setToasts((current) => [
...current,
{ id, message, type },
]);
setTimeout(() => {
setToasts((current) =>
current.filter((toast) => toast.id !== id)
);
}, 3000);
};
const removeToast = (id) => {
setToasts((current) =>
current.filter((toast) => toast.id !== id)
);
};
return { toasts, showToast, removeToast };
}4. Display Toast Notifications
Next, we can create a component called ToastContainer.jsx. The job of this component is to display all active notifications in one place. It acts as a container for all the toasts.
import Toast from "./Toast";
export default function ToastContainer({
toasts,
removeToast,
}) {
return (
<div className="fixed right-4 top-4 z-50 flex w-80 max-w-[calc(100vw-2rem)] flex-col gap-3">
{toasts.map((toast) => (
<Toast
key={toast.id}
message={toast.message}
type={toast.type}
onClose={() => removeToast(toast.id)}
/>
))}
</div>
);
}
5. Using the Toast System
Now, we can integrate the toast notification system we created into the App.jsx. We can check the toast messages by adding a test button that triggers the toasts.
import { useToast } from "./useToast";
import ToastContainer from "./ToastContainer";
export default function App() {
const { toasts, showToast, removeToast } = useToast();
return (
<div className="p-8">
<h1 className="mb-4 text-xl font-semibold">
Toast Notifications
</h1>
<div className="flex flex-wrap gap-3">
<button
onClick={() =>
showToast("Changes saved successfully!", "success")
}
className="rounded bg-green-600 px-4 py-2 text-white"
>
Success
</button>
<button
onClick={() =>
showToast("Something went wrong.", "error")
}
className="rounded bg-red-600 px-4 py-2 text-white"
>
Error
</button>
<button
onClick={() =>
showToast("You have a new notification.", "info")
}
className="rounded bg-blue-600 px-4 py-2 text-white"
>
Information
</button>
</div>
<ToastContainer
toasts={toasts}
removeToast={removeToast}
/>
</div>
);
}Our toast custom hook returns the showToast() function; we can use this function to trigger the toast. We can call this function wherever we want, like in an api function, form submission, or after a successful operation, etc.
Example toast for a successful operation
showToast("User created successfully!", "success");Example toast for a failed operation
showToast("Unable to create user.", "error");A toast notification is a useful addition to almost every React application. It gives quick feedback to the user without interrupting the user. In this blog we have created a basic toast notification system. We can extend this toast functionality by adding animations, accessibility features, etc. There are also ready-to-use packages for toast management that you can try.
To read more about How to Implement Push Notifications in a React PWA, refer to our blog, How to Implement Push Notifications in a React PWA.