Home > front end >  React setInterval Animation not triggered a second time
React setInterval Animation not triggered a second time

Time:10-20

There is an animation that I want to trigger every time the iot data changes, but it only works the first time.

Here Code:

  useEffect(async () => {

    function animate(elem, style, unit, from, to, time) {
        if (!elem) return;
        var start = new Date().getTime(),
            timer = setInterval(function () {
                var step = Math.min(1, (new Date().getTime() - start) / time);
                elem.style[style] = (from   step * (to - from))   unit;
                if (step == 1) clearInterval(timer);
            }, 25);
        elem.style[style] = from   unit;

    }
    animate(document.getElementById('id'), "height", "px", 0, 50, 1000);

}, [iot])

CodePudding user response:

Don't do this useEffect(async () => { The first argument of useEffect is supposed to be a function that returns either nothing (undefined) or a function. Instead write an async/await function in useEffect like this.

useEffect(() => {
  // declare the data fetching function
  const asyncFunction = async () => {
    // await whatever you need
  }

  // then call the function
  fetchData()
}, [])

So your async function should look something like const animate = async (elem, style, unit, from, to, time) => { // await...

async function returns a Promise, which can't be called as a function.

As far as why it only renders once, you haven't included anywhere in your snippet where iot changes or what it is. The dependency array will watch for iot, and when that changes, will trigger the side effect to rerun.

CodePudding user response:

I solved the problem. The problem was that I had unwittingly created multiple markers with the same id. When there were more than one element with the same id, I could not control them with css. I was trying to trigger this animation, which I want to be triggered when I click on the marker, by changing the iot data with eventhandlers and using the useeffect, but I gave up and ran the animation directly with the relevant id in the marker component and it worked without any problems.

Before Code:

Map Component

<Marker position={[s.lat, s.lng]} eventHandlers={{

                                    click: (e) => {
                                        setAIOT(iot)
                                    },

                                }

Temperature Component:

  useEffect( () => {

        function animate(elem, style, unit, from, to, time) {
            if (!elem) return;
            var start = new Date().getTime(),
                timer = setInterval(function () {
                    var step = Math.min(1, (new Date().getTime() - start) / time);

                    elem.style[style] = (from   step * (to - from))   unit;
                    if (step == 1) clearInterval(timer);
                }, 25);
            elem.style[style] = from   unit;

        }


        animate(document.getElementById("tlevel_"), "height", "px", 0, Math.abs(activeiotdevice.temperature), 1000);
    }, [activeiotdevice])



<div className="temperature">

            <div className="temperature-level " id="tlevel_">

            </div>

        </div>

After Code:

Map Component:

    function animate(elem, style, unit, from, to, time) {
        if (typeof elem !== "undefined") {
            var start = new Date().getTime(),
                timer = setInterval(function () {
                    var step = Math.min(1, (new Date().getTime() - start) / time);
                    elem.style[style] = (from   step * (to - from))   unit;
                    if (step == 1) clearInterval(timer);
                }, 25);
            elem.style[style] = from   unit;
            console.log(elem)

        }

    }

<Marker position={[s.lat, s.lng]} eventHandlers={{

                                    click: (e) => {
                                        animate(document.getElementById("tlevel_"   iot.id), "height", "px", 0, Math.abs(iot.temperature), 1000)
                                    },

                                }
                                }>

Temperature Component:

return (
        <div className="temperature">


            <div className="temperature-level} id={"tlevel_"   iottemp.id}>
            </div>

        </div>
    );
}
  • Related