Creating Twitter's increment like animation in React

When someone likes a tweet on Twitter, you see this effect on the counter:

Increment counter animation effect like Twitter

The old number flies to the moon, and the new number comes from the floor. I tried to simulate this effect using React; the trick is to animate the counter in 4 steps.

Let's take a look at the Counter.js component:

import React, { useState, useEffect } from 'react'; 
import  '../Styles/Counter.css';

const Counter = () => {
    const [likes, setLikes]                   = useState(0);
    const [animationLikes, setAnimationLikes] = useState('initial');
    const handleLikes = () => {
        // 1. Old number goes up
        setTimeout(() => setAnimationLikes('goUp'), 0);
        // 2. Incrementing the counter  
        setTimeout(() => setLikes(likes + 1), 100);
        // 3. New number waits down  
        setTimeout(() => setAnimationLikes('waitDown'), 100);
        // 4. New number stays in the middle
        setTimeout(() => setAnimationLikes('initial'), 200);

    return (
        <div className = 'Grid'>
            <div className = 'Likes' onClick = {handleLikes}>
                ❤️ <span className = {animationLikes}>{likes}</span>

export default Counter;

The key point is that you need to change dynamically the className using the variable animationLikes. Lastly, you need to apply translations to the counter.

Counter.css looks like this:

.Grid .Likes{
    cursor: pointer;
.Grid .Likes .goUp{
    display: inline-flex;
    opacity: 0;
    transform: translate3d(0, -20px, 0);
    transition: 0.1s ease-in-out;
.Grid .Likes .waitDown{
    display: inline-flex;
    opacity: 0;
    transform: translate3d(0, 20px, 0);
.Grid .Likes .initial{
    display: inline-flex;
    opacity: 1;
    transform: translate3d(0, 0px, 0);
    transition: 0.1s ease-in-out;

Hi, I'm Erik, an engineer from Barcelona. If you like the post or have any comments, say hi.