Reputation: 3444
I have a chart that I made with chartJS that I update in a way that makes an animation, and I do that with setInterval, I wanted to be able to pause/resume the animation.
So I created a state variable that tracks the interval ID so that I can kill it when the pause button is clicked:
const intervalIDs = [];
function App() {
const [times, setTimes] = useState(2); // variable that I need to change to make my animation work
const [allData, setAllData] = useState([]);
const [paused, setPaused] = useState(false);
const [animationIntervalID, setAnimationIntervalID] = useState();
useEffect(() => {
setAllData(calculateNewData()); // recalculate data for the chart when times changes
}, [times])
const startVisualizationHandler = () => {
console.log("called"); // gets called once as it should
setAnimationIntervalID(prevInterval => {
console.log("setting interval"); // this gets called just ONCE
let intervalID = setInterval(() => {
setTimes(prevTimes => prevTimes + 0.1);
}, 100);
intervalIDs.push(intervalID); // this pushes THREE interval ID's into the intervals array
return intervalID;
});
}
const pauseVisualizationHandler = () => {
clearInterval(animationIntervalID);
setAnimationIntervalID(prevID => undefined);
}
const resumeVisualizationHandler = () => {
startVisualizationHandler();
}
const handlePause = () => {
setPaused(pauseStatus => {
!pauseStatus ? pauseVisualizationHandler() : resumeVisualizationhandler();
return !pauseStatus;
});
}
return (
<>
<div style={{ maxHeight: 600, maxWidth: 600, height: 600, width: 600, display: "inline-block" }}>
<Line data={allData} options={options} width={null} height={null} />
<button id={"vishandler"} onClick={startVisualizationHandler}>
VISUALIZE
</button>
<button id={"pausehandler"} onClick={handlePause}>
{paused ? `RESUME` : `PAUSE`}
</button>
</div>
</>
);
}
When I run the code, with multiple console.logs spread out throughout the code, I have tracked everything, and when I click the pause/resume button, everything gets called just once in order, just like it should. However, the setAnimationIntervalID
within startVisualizationHandler
is acting extremely wierd, the console.log("setting interval");
gets called just once, but intervalIDs.push(intervalID);
gets called 3 times, because when I log intervalIDs I see 3 IDs.
What I am trying to do is:
-> onClick on the VISUALIZE
button -> start the animation - this is working, BUT it also ends up firing multiple setIntervals
(which to me basically means that the pause/resume functionality is irrelevant to the issue)
-> onClick on the PAUSE
button -> pause the animation - this is also working
-> onClick on the RESUME
button -> resume the animation - this is also working BUT it ends up firing multiple setIntervals
.
Upvotes: 0
Views: 77
Reputation: 10382
this is related to React.StrictMode
wrapping your App Application. StrictMode doesn't affect production, only development to find potencial problems. it does that by rerending your component, which results in these unexpected behavior.
to fix it, remove the wrapping StrictMode
tag from your App.
Upvotes: 1