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, 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:
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:
...
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.
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.
...
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.
...
<Toaster
toastOptions={{
className: '',
style: {
background: '#f87171',
color: '#ffe4e6',
}
}}
/>
...
Now let's create a div component to show the fetched data.
...
{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:
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 :)