'use Effect is repeating lottie animation
Learning React here, and I'm simply trying to display a lottie animation. Seems fairly straight-forward, but I'm having some trouble with the useEffect hook. I'm using the hook to render the animation on page load, but it keeps repeating itself (sometimes twice or more). I know this is because useEffect will fire more than once, but I'm not sure how to handle this. I just want one animation on the page. How can I achieve this?
import React, { useEffect, useRef } from "react";
import "./index.scss";
import lottie from "lottie-web";
const Hero = () => {
const lottieContainer = useRef(null);
useEffect(() => {
lottie.loadAnimation({
container: lottieContainer.current,
renderer: "svg",
loop: true,
autoplay: true,
animationData: require("../../assets/Lottie/developer.json"),
});
}, []);
return (
<div className="hero">
<div ref={lottieContainer}></div>
</div>
);
};
export default Hero;
Solution 1:[1]
It's because of React strict mode, it tries to help you to detect unwanted side effects and runs all useEffect
hooks twice, so you could see that you forgot something. And in that case you forgot to add cleanup function, without it lottie
creates 2 animations without cleaning up the first one. Just add this to your code:
useEffect(() => {
const instance = lottie.loadAnimation({
container: document.getElementById('lottie'),
renderer: 'svg',
loop: true,
autoplay: true,
animationData: require('../../../assets/Lottie/developer.json')
});
// Return clean up function here
return () => instance.destroy();
}, []);
Solution 2:[2]
useEffect
method as you have write it will execute the inside function when your component is mounted, your useEffect
is ok, your lottie config object has a loop
property that repeat your animation. You should replace by
lottie.loadAnimation({
container: lottieContainer.current,
renderer: "svg",
loop: false, //or delete this line
autoplay: true,
animationData: require("../../assets/Lottie/developer.json"),
});
Solution 3:[3]
import React, { useEffect, useRef } from "react"; import "./index.scss"; import lottie from "lottie-web";
const Hero = () => { const lottieContainer = useRef(null);
useEffect(() => { constinstance = lottie.loadAnimation({ container: lottieContainer.current, renderer: "svg", loop: true, autoplay: true, animationData: require("../../assets/Lottie/developer.json"), }); return () => instance.destroy(); }, []);
return ( ); };
export default Hero;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Danila |
Solution 2 | enzou |
Solution 3 | Emranul Farhad |