Create smoking hot toast notifications in React with React Hot Toast. 🔥
Tags: react, javascript, webdev, tutorial
Published: 2021-03-22 14:10:48

Ding ding! A new toast shop is around your town and what a unique take to make toasts! But more importantly, to notify others of their presence!

Well, what is this new toast? How does it help developers in particular? Here’s all you need to know about the hottest new React library to make toast notifications.


## About the library

> [**React Hot Toast**](https://react-hot-toast.com) is a library that aims to include toast notifications in your React applications easily and intuitively. 

It’s a three-step process to add the simplest of all notifications in your app. But before we even start doing anything with it, we need to take a look at some of the features it has to offer.

Here are its top 5 features:

1. **Easy to use**: just three simple steps needed to start.
2. **Lots of customizations**: there are many ways you can set a notification to your liking.
3. **Uses native [Promise API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)**: after all, everything is in JavaScript so why not use its wonderful event feature!
4. **Support for headless hooks**: by this, you can make your custom notifications. 
5. **Supports emojis**! 🤩

Now that we have some information, here’s what the rest of the blog will tell you about:

- [Installation](#installation)
- [A basic demo](#basic-demo)
- [API references with examples](#api-references)
- [A smoking hot real-life example](#a-practical-example)
- [Conclusion ](#conclusion)


## Installation

Ready to start off making some toasts? Let’s begin by creating an empty React project from scratch. Open up your terminal and run the following commands:

```bash 
npx create-react-app hot-toast-demo 
cd hot-toast-demo 
npm start
```

This will start a new React project on the current directory and will run it on your default browser window. Let’s just do the necessary things first. It’s time to install the [react-hot-toast package](https://www.npmjs.com/package/react-hot-toast)!

On the terminal, under the same project directory, run the following command:

```bash
npm install react-hot-toast
```
Or, if you are using Yarn as the package manager:
```bash
yarn add react-hot-toast
```


## Basic demo

Now that we have the library installed, we can go ahead and do some changes. We will modify the entry-level _app.js_ file so that we have a very basic interface to kick things off.

Simply remove all the code you have on the file and then follow the below steps to have an interface similar to this:

![Notification demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3abo8j8xkwiqhae7tgil.gif)


As you can see we have three buttons, the first one simply sends a toast notification with a text message, the second one is a success toast message which tells us that the action you did was successful, and the third button is just the opposite, it notifies that the action was not successful.

Okay, let’s code now.

### Step 1: Build the interface

```js
export default function App() {
 return (
   <div className="App">
     <h1>React Hot Toast 🍞</h1>
     <button onClick={notify}>Make me a toast</button>
     <button onClick={sucessNotify}>Make me a sucess toast</button>
     <button onClick={errorNotify}>Make me a error toast</button>
     <Toaster />
   </div>
 );
}
```
Under the default App export, we have one `<h1>` heading and three buttons `<button>` with their `onClick` handlers like `notify`, `sucessNotify` and `errorNotify` linked to three different functions which are defined outside the `App()` scope. Next, we have the <Toaster /> component which comes from the `react-hot-toast` package we installed earlier. So, make sure you import the following line:

```js
import { Toaster } from "react-hot-toast";
```
The notification that pops up after clicking the button comes from the `Toaster` component. Next, let’s add the notify logic by working on the functions.

### Step 2: Add the notifications

We have three things to do here, the usual text notification, the success one, and then the error notification.

#### Adding the _basic_ notification:

```js
const notify = () => toast("Here is my toast!");
```
The `notify` function simply takes in the `toast` function. Inside it, we can pass any text we want to display in the notification toast. Notice we are using the [arrow syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) here to write our function.

#### Adding the _success_ notification:

```js
const sucessNotify = () => toast.success("Sucess!");
```
The `successNotify` creates an animated check mark notification. For that, we need to call in the `toast.success()` method. Just pass in any string you want to show alongside the check icon.

#### Adding the _error_ notification:

```js
const errorNotify = () => toast.error("Error");
```
This creates a toast notification with an animated cross icon. Simply call the `toast.error()` method. Just pass in any string you want to show alongside the cross icon.

Here’s our entire code for now:

```js
import toast, { Toaster } from "react-hot-toast";

const notify = () => toast("Here is my toast!");
const sucessNotify = () => toast.success("Sucess!");
const errorNotify = () => toast.error("Error");

export default function App() {
 return (
   <div className="App">
     <h1>React Hot Toast 🍞</h1>
     <button onClick={notify}>Make me a toast</button>
     <button onClick={sucessNotify}>Make me a sucess toast</button>
     <button onClick={errorNotify}>Make me a error toast</button>
     <Toaster />
   </div>
 );
}
```
Now click on each button we made and it will pop up the notification presets we added!

## API references

We are about to build something more usable now. Before we do that, we first need to understand its two important APIs:

### 1. The [`toast()`](https://react-hot-toast.com/docs/toast) API

This is the most basic API from where all the toasts are made. You can call this method anywhere you like. It even works outside React. For it to work, you need to define the `<Toaster />` component first.

Apart from the three methods used in the above examples the `toast()` API has the following two advanced usages:

- 1. **The _Loading_ state**: this is used when you need to define that the action done by the user is currently being processed.

```js
toast.loading('Waiting for the action to complete...');
```
But using only the loading indication _should be avoided_ as we can’t end this action, the notification will persist indefinitely causing the app to use more resources and finally, slowing it down. Instead, we can use the next alternative…

- 2. **The _Promise_ state**: this is based on the asynchronous Promise concept of ES6. It maps the Promise to the notification used and updates automatically when the Promise is resolved or failed. You can give proper arguments as to what needs to be there in the toast for either of the cases.

```js
 toast.promise(myPromise, {
 loading: 'Data is loading...',
 success: 'Got the data!',
 error: 'Error when fetching data :(',
});
```

### 2. The [`Toaster`](https://react-hot-toast.com/docs/toaster) API

Here things get exciting. You can _make your own notifications_ from this API. You can render any component you want, all `Toaster` does is that it provides the notification’s current state.

Here’s an example:

```js
const buildNotification = () => {
 const { myToasts } = useToaster();

 return (
   <div>
     {myToasts.map((toast) => (
       <div>{toast.message}</div>
     ))}
   </div>
 );
};

toast('Hey toast!');
```

## A practical example

Let’s make a more practical example with this library. Here’s what we are trying to achieve:

{% codesandbox react-hot-toast-demo-2-zotek %}

As you can see in the embed above, this is a chat-like interface where you can type your message in the input and hit the “Send a hot toast 🍞 ” button to get a customized toast notification. Moreover, if you try to send toast several times, you see the notification which came earlier goes away first with a transition, and if you start hovering the cursor over any of these elements, the notification stays there, just like we have on our systems! It goes away when you stop hovering.

Note that the input box does nothing but shows you a practical scenario where we can use this library. We have a lot to explore here, so let’s get to code.

### Step 1: Code the interface

There are three UI elements here:

- The input field
- The button
- The notification itself

```js
return (
   <div className="App">
     <HotToastNotifications />
     <input placeholder="Write your toast here..." />
     <button onClick={() => toast("🛎 Toast message sent!")}>
       Send a hot toast 🍞
     </button>
   </div>
 );
 ```
On the `onClick` of the button we need to fire the `toast()` method wherein we add the string needed to show on the notification. Here it says, "🛎 Toast message sent!". We render the notification component named `HotToastNotifications` beforehand.

Next, let’s make something unique. Here, we will be using the [`useToaster()`](https://react-hot-toast.com/docs/use-toaster) headless API to make our custom component from scratch.

### Step 2: Create handlers and the notification component

```js
const { toasts, handlers } = useToaster();
```
In the `HotToastNotifications` component, we first define the two handlers for `useToaster()` i.e. `toasts` and `handlers`. The first one will be used to map over the number of notifications to render and the latter is to add the hover-based handling.

```js
toasts.map((toast) => {
       const offset = calculateOffset(toast.id, {
         reverseOrder: false,
         margin: 10
       });
```
       
Using JavaScript’s native [`map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) method, we loop over each individual `toast` element, calculating its `offset` position defined on the `calculateOffset` handler of `useToaster` API. In this, we need to pass the `toastId` which is a unique identifier for each toast, the `reverseOrder` which is a boolean property to state whether notifications appear in reverse order or not, and the `margin` between each notification when they appear together. 

### Step 3: Create a custom shape of the component

```js
const ref = (el) => {
         if (el && !toast.height) {
           const height = el.getBoundingClientRect().height;
           updateHeight(toast.id, height);
         }
       };
 ```

Next, to make the shape of the custom notification, we are using the [`getBoundingClientRect()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect) method on the element which returns [`DOMRect`](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect) object to get the precise size of the `height` of the element. Then with the `updateHeight` handler, we set it to the toast’s ID and the calculated height.

### Step 3: Style the notification

```js
return (
         <div
           role="alert"
           aria-label="notification"
           key={toast.id}
           ref={ref}
           style={{
             position: "absolute",
             width: "13rem",
             padding: "0.7rem",
             background: "rgba(175, 75, 62, 0.1)",
             borderRadius: "3rem",
             transition: "all 0.2s",
             transform: `translateY(${offset}px)`,
             opacity: toast.visible ? 1 : 0
           }}
         >
           {toast.message}
         </div>
       );
```

Time to add some styles to the custom notification we just made! You can choose any HTML element to make them but usually `<div>` works just fine. We give it the necessary `key` which is the ID of the toast, the `ref` element we made above, and finally, the `style` property where you can add any CSS styling to your need. Notice that we have dynamic `opacity` here so when `toast` is removed, it turns the opacity to `0` else, it stays at `1`. 

### Step 4: Create the hover based interactions

Finally, we have one last thing left. We want that until we hover the notification, it shouldn’t go away. It can go when we remove hovering. 

```js
<div
     style={{
       position: "fixed",
       top: 10,
       left: 10
     }}
     onMouseEnter={startPause}
     onMouseLeave={endPause}
   >
```

To make this possible we make the same `<div>` element but we do two important things; first, we need to style it such a way that its position stays the same until we remove the hover, and second, we use `onMouseEnter` and `onMouseLeave` events and set it to the `startPause` and `endPause` handlers respectively. 

And that’s it! If you implement all the code above you can now play with your own custom toast notification sent whenever the `onClick` event is triggered! Here’s the entire code of the custom notification component we made:

```js
const HotToastNotifications = () => {
 const { toasts, handlers } = useToaster();
 const { startPause, endPause, calculateOffset, updateHeight } = handlers;
 return (
   <div
     style={{
       position: "fixed",
       top: 10,
       left: 10
     }}
     onMouseEnter={startPause}
     onMouseLeave={endPause}
   >
     {toasts.map((toast) => {
       const offset = calculateOffset(toast.id, {
         reverseOrder: false,
         margin: 10
       });
       const ref = (el) => {
         if (el && !toast.height) {
           const height = el.getBoundingClientRect().height;
           updateHeight(toast.id, height);
         }
       };
       return (
         <div
           key={toast.id}
           ref={ref}
           style={{
             position: "absolute",
             width: "13rem",
             padding: ".7rem",
             background: "rgba(175, 75, 62, 0.1)",
             borderRadius: "3rem",
             transition: "all 0.2s",
             transform: `translateY(${offset}px)`,
             opacity: toast.visible ? 1 : 0
           }}
         >
           {toast.message}
         </div>
       );
     })}
   </div>
 );
};
```

### Conclusion

Wasn’t it that easy! I mean, the ability to use hooks to make a custom notification is so mind-blowing and that comes with such ease to make. Let me know how you will be using this library, you can surely open a new issue to [its GitHub](https://github.com/timolins/react-hot-toast) and let the library author know of any bugs you encountered or a new feature to include!

---

Hope you liked the information. You can comment below with your thoughts about it.

And now...as always, enjoy a meme! 😆

---

## The [#DevHumour](https://twitter.com/search?q=%23devhumour&src=typed_query) Corner 😂

![Dev Humour Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hn0vrd4udwqsix4x129t.jpeg)

---

## Some of my previous articles

- [5 really cool web technologies to know! 🤩](https://dev.to/vaibhavkhulbe/5-really-cool-web-technologies-to-know-2maj)
- [5 quick and easy fixes to improve your React app performance 🚀](https://dev.to/vaibhavkhulbe/5-quick-and-easy-fixes-to-improve-your-react-app-performance-5g43)
- [Demystifying 15 lesser-known React Redux terms and features (With examples) 🔮](https://dev.to/vaibhavkhulbe/demystifying-lesser-known-redux-terms-and-features-with-examples-112k)

---

## Find me on

| [Twitter 🐦](https://twitter.com/vaibhav_khulbe)  | [Instagram 📸](https://instagram.com/vaibhavkhulbe143/)   | [LinkedIn 👨🏻‍💻](https://www.linkedin.com/in/vaibhav-khulbe/)  | [Everywhere else 🌐](https://about.me/vaibhav_khulbe)
|---|---|---|---

---

#### [📫 Subscribe to my weekly developer newsletter 📫](https://mailchi.mp/f59beeac6b9b/devupdates)