Daily Emoji - My first NextJS project
Tags: nextjs, react, webdev, javascript
Published: 2022-06-25 14:00:52

You can check it live [here](https://dailyemoji.vercel.app/)
You can check the full code [here](https://github.com/LLxD/daily-emoji)

## Intro
The idea of this website, is just to randomize an emoji for the user and make it copiable. It is my first NextJS project.

## Steps

So, there are a few steps I followed to create this project:

- Fetch a few emojis from the [https://emojihub.herokuapp.com/](Emojihub API)
- Create a "rolling" animation, after the used click the randomize button
- Show the randomized emoji
- Make it copiable for the user
- Signal if the user copied


## Fetching from the API

```react

import { useState, useEffect } from "react";

 const UrlToFetch =
"https://emojihub.herokuapp.com/api/all/category_smileys_and_people";

  const [emoji, setEmoji] = useState([{ htmlCode: "" }]);

  const [isLoaded, setIsLoaded] = useState(false);

  const fetchEmoji = () => {
    fetch(UrlToFetch)
      .then((res) => res.json())
      .then((emoji) => setEmoji(emoji))
      .then(() => setIsLoaded(true));
  };



```

Here is the snippet of code that fetches from the API. After the fetch, it stores all emojis in a state called emoji and set the variable isLoaded to true, making the UI show the loaded emoji.

## The "rolling" animation and showing the randomized animation

So, initially, I was thinking to create an animation like a casino-styled roll, but, after searching a little bit (and realizing I would probably need to create a LOT by hand) I decided to make an easier animation, that would just rapidly change between a few emojis.

```react

  const [loadingEmoji, setLoadingEmoji] = useState("&#128512;");
  const [finishedAnimation, setFinishedAnimation] = useState(false);
  const [timeLeft, setTimeLeft] = useState(5);

  useEffect(() => {
    const loadingEmojis = [
      { htmlCode: ["&#129315;"] },
      { htmlCode: ["&#128538;"] },
      { htmlCode: ["&#128071;"] },
      { htmlCode: ["&#9996;"] },
      { htmlCode: ["&#129310;"] },
      { htmlCode: ["&#128406;"] },
    ];
    if (timeLeft === 0) {
      setFinishedAnimation(true);
      setTimeLeft(null);
    }
    if (!timeLeft) return;
    const intervalId = setInterval(() => {
      setLoadingEmoji(getRandomEmoji(loadingEmojis));
      setTimeLeft((timeLeft) => timeLeft - 1);
    }, 333);
    return () => clearInterval(intervalId);
  }, [getRandomEmoji, timeLeft]);


```

This snippet represents the general idea of the animation, we have a set of emojis and a variable called timeLeft (which represents the time left for the animation to run) initialized with 5. If there is still time left, we create a interval function, that will set a new loadingEmoji and decrease the timeLeft by 1.

If all that is executed and there is no time left, we set finishedAnimation to true and the UI reacts to that.

To animate the showing of the result, I used [animate.css](https://animate.style/)

```react

import "animate.css";

<div
  className={
     styles.description +
     " animate__animated animate__tada animate__delay-2s"
     }
     dangerouslySetInnerHTML={{
     __html: emoji,
     }}
></div>
```

This is the final result:
![GIF of the final result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/48fzy4u853b16jvmf4bh.gif)



## Making it copiable for the user

I used [copy-to-clipboard](https://www.npmjs.com/package/copy-to-clipboard) to make it easier to copy into the clipboard of the user.

```react

  const copyToClipboard = () => {
    copy(document.querySelector("#emoji").innerHTML);
  };

  <div
        onClick={() => copyToClipboard()}
        className={
          styles.description +
          " animate__animated animate__tada animate__delay-2s"
        }
        dangerouslySetInnerHTML={{
          __html: emoji,
        }}
        id="emoji"
        data-tip="Click on it to copy <br>to your clipboard!"
      ></div>

```


## Signal for the user that the emoji was copied

For showing the user that the emoji was copied to his clipboard, I used the [React-toastify](https://fkhadra.github.io/react-toastify/introduction/), to create an easy and beautiful notification.

```react

import { ToastContainer, toast } from "react-toastify";

  const notify = () => toast("Copied to clipboard!");

  const copyToClipboard = () => {
    copy(document.querySelector("#emoji").innerHTML);
    notify();
  };


      <ToastContainer
        position="top-right"
        autoClose={2000}
        theme="dark"
        pauseOnHover={false}
      />

```

And that's it! I also added a few tooltips, to make it more user friendly using [react-tooltip](https://github.com/wwayne/react-tooltip), but that is completely optional.

I deployed it to [Vercel](https://vercel.com/) with a lot of ease and that's all!

Thanks for reading!