My component renders an image every 4 seconds. When I click on the image I want to stop rendering new images. For that I've used a useEffect hook. When I click to the image, the state hasToRefresh
changes it's values, but inside useEffect it doesn't change. This is my code:
import { useEffect, useState } from "react";
const VariableImage = () => {
const imageUrl = "https://picsum.photos/200";
const imageRefresh = "?forcerefresh=";
const [image, setImage] = useState(imageUrl);
const [hasToRefresh, setHasToRefresh] = useState(true);
useEffect(() => {
if (hasToRefresh) {
setInterval(() => {
setImage(imageUrl + imageRefresh + Math.random());
}, 4000);
}
}, [imageUrl, imageRefresh, hasToRefresh]);
return (
<>
<img
src={image}
onClick={() => setHasToRefresh(!hasToRefresh)}
alt="scenery"
height="200"
width="200"
/>
</>
);
};
export default VariableImage;
Also in sandbox: https://codesandbox.io/s/variable-image-zxhejs
How can I do for when I click the image to not render more images? If anyone could help me I would be very grateful. Thanks.
As Roy Schut mentioned, you never stop your timer. But the best option would be here to stop the timer when the image shouldn't be refreshed. Here's the code I would prefer.
import { useEffect, useState, useRef } from "react";
const VariableImage = () => {
const imageUrl = "https://picsum.photos/200";
const imageRefresh = "?forcerefresh=";
const [image, setImage] = useState(imageUrl);
const [hasToRefresh, setHasToRefresh] = useState(true);
const intervalRef = useRef(null);
useEffect(() => {
startTimer();
return () => stopTimer();
}, []);
const startTimer = () => {
intervalRef.current = setInterval(() => {
setImage(imageUrl + imageRefresh + Math.random());
}, 4000);
};
const stopTimer = () => {
clearInterval(intervalRef.current);
};
const toggleRefresh = () => {
if (hasToRefresh) {
stopTimer();
} else {
startTimer();
}
setHasToRefresh(state => !state);
};
return (
<>
<img
src={image}
onClick={() => toggleRefresh()}
alt="scenery"
height="200"
width="200"
/>
</>
);
};
export default VariableImage;