Learn how to create an animated refreshing icon in React when clicked

I have a refresh icon in my React app that utilizes Material UI. I want the icon to spin for a second after it is clicked, but I am unsure of how to achieve this.

Despite attempting some solutions, none have been successful.

const useStyles = makeStyles((theme) => ({
refresh: {
    marginTop: "20px",
    cursor: "pointer",
    margin: "auto",
    animation: "spin 1s 1",
  },
  "@keyframes spin": {
    "0%": {
      transform: "translateY(-200%)",
    },
    "100%": {
      transform: "translateY(0)",
    },
  },
}));

function Refresh() {
    const [spin, setSpin] = React.useState(0);
    const classes= useStyles();
    
    const refreshCanvas = () => {
        setSpin(1);
        console.log("Refreshed");
    };
    return (
        <AutorenewIcon
            className={classes.refresh}
            onClick={refreshCanvas}
            onAnimationEnd={() => setSpin(0)}
            spin={spin}
        />
    )
    
}

Answer №1

Toggle the spin to true when clicked, then set a setTimeout for 1000ms to switch the spin state back to false. Based on the value of the spin state, conditionally add a class and apply animation to that class.

const useStyles = makeStyles((theme) => ({
    refresh: {
        marginTop: "20px",
        cursor: "pointer",
        margin: "auto",
        "&.spin": {
            animation: "$spin 1s 1",
            // pointerEvents:'none'
        }
    },
    "@keyframes spin": {
        "0%": {
            transform: "rotate(0deg)"
        },
        "100%": {
            transform: "rotate(360deg)"
        }
    }
}));

function Refresh() {
    const [spin, setSpin] = React.useState(false);
    const classes = useStyles();

    const refreshCanvas = () => {
        setSpin(true);
        setTimeout(() => {
            setSpin(false);
        }, 1000);
    };

    return (
        <Autorenew
            className={clsx({
                [classes.refresh]: true,
                spin: spin
            })}
            onClick={refreshCanvas}
            spin={360}
        />
    );
}

Optional Update: You can include pointerEvents:"none" in the spin class to disable clicking during the animation period of 1000ms.

Check out the live demo:
https://codesandbox.io/s/amazing-burnell-m9j4y?fontsize=14&hidenavigation=1&theme=dark

Answer №2

To differentiate the class for animation, let's say it is currently named refresh and stored in classes.refresh.

You can achieve this by conditionally applying the className to your element.

function UpdateAnimation() {
    const [rotate, setRotate] = React.useState(0);

    const classes= useStyles();

    const animateRefresh = () => {
        setRotate(1);
        console.log("Animated Refresh");
    };

    return (
        <AutorenewIcon
            className={rotate === 1 ? classes.refresh : ''}
            onClick={animateRefresh}
            onAnimationEnd={() => setRotate(0)}
            rotate={rotate}
        />
    )
}

Answer №3

Received the solution! Grateful for the valuable answers provided here, they truly inspired me.

const customStyles = makeStyles((theme) => ({
      reload: {
        margin: "auto",
      },
      rotating: {
        margin: "auto",
        animation: "$rotate 1s 1",
      },
      "@keyframes rotate": {
        "0%": {
          transform: "rotate(0deg)",
        },
        "100%": {
          transform: "rotate(360deg)",
        },
      }
    }))
    
    function Refresh() {
    const [rotate, setRotate] = React.useState(0);
    
const styles= customStyles();

const renewScreen = () => {
    setRotate(true);
    setTimeout(() => {
      setRotate(false);
    }, 1000);
    console.log("Screen refreshed successfully!");
};
return (
    <AutorenewIcon
        className={rotate ? styles.rotating : styles.reload}
        onClick={renewScreen}
        rotate={rotate}
    />
  )
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Incorporate audio playback on image click using JavaScript, with the feature to automatically pause the playback if multiple images are playing simultaneously

<img class="cl" src="photo/198.jpg"/></br> <audio class="cs" controls> <source src="audio/198 banu nagamothu.mp3" type="audio/mpeg"> </audio> I prefer not to have audio controls initially, but when the image i ...

The issue of unselection not functioning properly for multiple items when using both selectable and draggable features

i need the unselection of list items to be as smooth as selectable() but without draggable() My desired outcome is similar to the following gif showcasing combined selectable and draggable functionality: https://i.stack.imgur.com/3GjTD.gif here's t ...

AngularJS POST request encounters failure: Preflight response contains improperly formatted HTTP status code 404

I have encountered a persistent issue with microframeworks while attempting to perform a simple POST request. Despite trying multiple frameworks, none of them seem to handle the POST request properly: Here is an example using AngularJS on the client side: ...

Encountering issues with app functionality following update to Ionic RC4 version

Since upgrading from Ionic rc3 to rc4, I've been facing difficulties running my app smoothly. The app compiles without any errors when I use ionic-app-scripts build --prod, but when I try to run it on my iPhone, all I get is a blank screen and an err ...

Creating a button that integrates an image within a single div element

Currently, I understand the code: $('#leftDev').css("background-image", "url(img/1.png) "); will set the entire background of my leftDiv to display "1.png". However, I would like to position this image as a regular picture within the div and no ...

Leveraging fetch for sending JSON payloads

I am currently facing an issue while attempting to post multiple points of data from a form input. Despite my efforts, it seems that the form data does not make it to the json output payload as expected. I have verified this through network output inspect ...

Obtain the origin of the image using dots in Javascript

Sharing my experience with setting a background image using Javascript. Initially, I tried using two dots like this: .style.backgroundImage = "url('../images/image00.jpg')" However, it did not work as expected. So, I removed one dot: .style.ba ...

Creating a React application and configuring it to work with an Express server

During my attempt to incorporate Stripe into React, I encountered the need to set up a Node.js Express server. After successfully configuring the server and making some modifications to my package.json, as well as creating a new server.js file, it now retu ...

The background of the section does not extend to the full height

Currently, I am using the <section> tag as a background for a specific section on my website. However, I am facing an issue where the height of the background is being cut off, even though the content continues below it. I have attempted various pos ...

Animating distance with the power of animate.css

I have implemented animate.css for a login form, but it is not behaving as desired. Currently, I am utilizing the fadeInDown animation, however, it is fading in from a greater distance than intended. I would prefer it to fade in from just around 20px below ...

The first time I try to load(), it only works partially

My script used to function properly, but it has suddenly stopped working. Can anyone help me figure out why? The expected behavior is for the referenced link to be inserted into target 1, while target 2 should be updated with new content from two addition ...

Access the JSON data containing sub array values and showcase them on an HTML page by utilizing ngFor

Greetings! I am currently working on a web application where I need to showcase student data that is being received in JSON format. Below is the TypeScript code snippet that outlines the structure of the student data: export interface studentData{ ...

React random marker position shifts when the screen size is adjusted

After displaying an image and adding a marker to it, I noticed that the marker's position changes when the screen size is adjusted. Why does this happen? And more importantly, how can I ensure that the marker stays in the same position relative to the ...

Unable to load dynamic data in Angular 2 smart table

Currently, I am utilizing Angular 6 along with smart table by visiting this link: . Everything was functioning smoothly, until the moment I attempted to switch from static to dynamic data: The following code works perfectly and displays all the content ...

Having trouble with React Testing Library throwing an error every time I try to use fireEvent on an input text?

When attempting to utilize the "fireEvent" method from React Testing Library, I encountered an error as shown below: https://i.sstatic.net/ExH4u.png MainSection.test.js: test('Verifying SearchBar functionality', async () => { render(< ...

Tips for deleting the drop-down arrow from Mozilla Firefox

Is there a way to eliminate the dropdown arrow that FireFox usually displays? I have included an image below showing what I am referring to: This is the CSS code I'm using: @-moz-document url-prefix(){ .class select { width: 110%; } } .class > ...

The negation functionality in the visible binding of Knockout.js is not functioning properly

I'm having trouble using the visible data binding with a negation and it's not functioning as expected. I've come across various posts on stackoverflow suggesting that the NOT binding should be used as an expression. However, in my scenario, ...

Error message encountered in node-schedule: Unable to read undefined property upon job restart

Using node-schedule, I have successfully scheduled jobs on my node server by pushing them into an array like this: jobs.push(schedule.scheduleJob(date, () => end_auction(req.body.item.url))); Everything is working as expected. When the designated date ...

Incorporate PHP form and display multiple results simultaneously on a webpage with automatic refreshing

I am currently in the process of designing a call management system for a radio station. The layout I have in mind involves having a form displayed in a div on the left side, and the results shown in another div on the right side. There are 6 phone lines a ...

The POST request from the form is returning a null value

I am currently facing an issue with using post in Express and BodyParser to insert data from a form in an EJS file into MySQL. The data keeps returning null, indicating that it is not being parsed correctly from the form to the backend. Can anyone offer as ...