You could do something like this:
Solution 1: Add dependency array to the useEffect
.
const [dosa, setDosa] = useState([]);
const hola= () => {
const haspi = dv?.map((id) => {
fetch(`https://www.roads.com/roads/roadscontroll/${id}`)
.then((response) => response.json())
// To avoid confusion use different name for the received data: dosa -> newDosa
.then((newDosa) => setDosa((prev) => [...prev, [newDosa]))
.catch((error) => console.error(error))
})
return haspi ;
}
useEffect(() => {
hola();
}, []); // Add empty dependency array here
Adding an empty dependency array prevents the useEffect
from being called on every render. This way it is called only on the component mount.
This issue is occurring because you are calling setDosa
on API success which causes the dosa
state to update and the component to re-render and this causes the useEffect
(with no dependency) to get called over and over again in a "loop".
More info on the difference between no dependency array and an empty dependency array over here: https://stackoverflow.com/a/66385496/7040601
Solution 2:
Below is a less elegant solution to store the counter using a ref object and setting a limit to the counter.
const [dosa, setDosa] = useState([]);
const counterRef = useRef(0); // Ref initialied to value = 0
const limit = 3;
const hola= () => {
const haspi = dv?.map((id) => {
fetch(`https://www.roads.com/roads/roadscontroll/${id}`)
.then((response) => response.json())
.then((newDosa) => setDosa((prev) => [...prev, [newDosa]))
.catch((error) => console.error(error))
})
return haspi ;
}
useEffect(() => {
// Only call `hola()` if counter is within the limit
if(counterRef.current < limit)
hola();
counterRef.current++; // Increment the counter by 1
});
Note: In addition to this, I agree with @Peter Tam's suggestion in the comments, you may apply it on top of the above solutions:
I perfer to use a temp array to store all the fetch records, and set state at last instead of setting state everytime after fetch request is returned. Maybe there are issues for using not updated states. You may follow the answer like here.