Create beautiful loading notification in React in 20 lines of code!
Tags: javascript, webdev, react, productivity
Published: 2022-05-17 12:23:08

## The Idea
I'll be honest here, JavaScript alerts on browsers suck! I've been trying to find the perfect library to create notification and toasts easily in react and here's what I found out 😀

## The Library
I was able to find some react component library for creating toasts but the easiest to implement and cleanest library that I found was [react-hot-toast](https://github.com/timolins/react-hot-toast), **Warning: It's too hot!**

## Creating the toast
Using the library is pretty easy, and there are a a number of different toasts available which you can check out in their docs page, but for this blog, we will focus on the **promise** toast to create a loading notification when we fetch data from an API.

Let's start by creating a react project.

Dependencies I installed in the example app:
- tailwind
- react-hot-toast

Let's quickly get to the part where we fetch data from an API. I have an API to get my Spotify data and I'll be using that here.

My `app.jsx` file:
```js
import { useState } from 'react'
import toast, { Toaster } from 'react-hot-toast';

function App() {
  const [data, setData] = useState(null)
  function fetchData() {
    return fetch('https://spotify-np-api.vercel.app/api').then(
      (response) => {
        return response.json();
      }
    ).then(
      (data) => {
        return data;
      }
    ).catch(
      (error) => {
        console.error(error);
      }
    )
  }
  const getToast = () => {
    toast.promise(fetchData(), {
      loading: 'getting song data...',
      success: (data) => {
        setData(data)
        return 'fetched top song data'
      },
      error: "couldn't fetch data!",
    })
  }

  return (
    <div className="relative App flex justify-center items-center bg-red-200 w-screen h-screen flex-col gap-3 p-3">
      <button onClick={getToast} className='hover:rotate-3 duration-300 bg-red-400 -rotate-3 shadow-xl rounded-md px-6 py-2 text-rose-100 font-bolder' >🎵ㅤGet Song Data</button>
      {data && 
        <div className='hover:-rotate-1 duration-300 cursor-pointer bg-red-400 flex flex-col rotate-1 justify-center items-center h-1/4 w-full lg:w-1/3 md:w-1/2 shadow-2xl rounded-md p-4'>
          <h1 className='text-center text-2xl mb-3 text-red-100 font-bold'>ashish's top song for this week 🎵</h1>
          <h1 className='text-center text-xl font-bolder text-rose-100'>{data.top.song.toLowerCase()}</h1>
          <h1 className='text-center text-md font-bolder text-rose-200'>~ {data.top.artist}</h1>
        </div>
      }
      <h2 className='text-red-600 text-sm absolute bottom-0 text-center p-4'>made by ashish using react-hot-toast</h2>
      <Toaster
        toastOptions={{
          className: '',
          style: {
            background: '#f87171',
            color: '#ffe4e6',
          }
        }}
      />
    </div>
  )
}

export default App
```

Let's break it down now.

Function for fetching and returning the promise, It returns the promise to be used by our toast method:
```js
...
function fetchData() {
  return fetch('https://spotify-np-api.vercel.app/api').then(
    (response) => {
      return response.json();
    }
  ).then(
    (data) => {
      return data;
    }
  ).catch(
    (error) => {
      console.error(error);
    }
  )
}
...
```

Now let's implement our react-hot-toast! First of all we will need to import it in our file.
```js
import toast, { Toaster } from 'react-hot-toast';
...
```

`OnClick` function using `toast.promise()`, we need to pass our promise in the `toast.promise()` method and the second argument is an object `msgs` where we define the messages that the toast needs to show based on promise state. Note that you can use a function to set states and change data in here too. I have used `setData()` to update the data to be displayed on app if the promise is fetched successfully.
```js
...
const getToast = () => {
  toast.promise(fetchData(), {
    loading: 'getting song data...',
    success: (data) => {
      setData(data)
      return 'fetched top song data'
    },
    error: "couldn't fetch data!",
  })
}
...
```

We need to add the `<Toaster />` component at the end of our app to render the toast, You can style the toast here using `ToastOptions` object passed to it.

```js
...
<Toaster
  toastOptions={{
    className: '',
      style: {
      background: '#f87171',
      color: '#ffe4e6',
    }
  }}
/>
...
```

Now let's create a div component to show the fetched data.
```js
...
{data && 
        <div className='hover:-rotate-1 duration-300 cursor-pointer bg-red-400 flex flex-col rotate-1 justify-center items-center h-1/4 w-full lg:w-1/3 md:w-1/2 shadow-2xl rounded-md p-4'>
          <h1 className='text-center text-2xl mb-3 text-red-100 font-bold'>ashish's top song for this week 🎵</h1>
          <h1 className='text-center text-xl font-bolder text-rose-100'>{data.top.song.toLowerCase()}</h1>
          <h1 className='text-center text-md font-bolder text-rose-200'>~ {data.top.artist}</h1>
        </div>
      }
...
```

And with this, we have successfully made a simple app to fetch data from API and show it with a beautiful toast. Here's what the final app looks like: 
![gif](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8fesqeb9gymm1iberbn9.gif)

Thanks for reading if you made it till here, Hit me up with questions or anything you want to ask in comments, I will reply asap :)

[Source Code](https://github.com/asheeeshh/react-loading-toast-example)