I was creating a custom hook in React when I encountered behaviour of useEffect hook that I was not expecting. I created a custom hook that takes an array of IDs and fetches data for every ID and whenever the IDs change, it fetches again and then returns all of the data in one array:
const useGetItems = (ids) => {
const [data, setData] = useState([]);
useEffect(() => {
const loadData = async () => {
const responses = ids.map((id) => fetchById(id));
const parsed = await Promise.all(responses);
setData(parsed);
};
loadData();
}, [ids]);
return data;
};
However, when I tested it with an array of IDs defined like const ids = [1,2] and passed them into useGetItems, the useEffect hook started to loop endlessly. After some debugging, I found that when I put ids into state using useState, the issue is gone. Also commenting out the setData caused the endless loop to stop.
You can find the full example here. You can uncomment problematic lines and see a log of every call of fetchById in the console.
Why does it behave like this? Is it because the data outside React state are not equal when compared by React even if they don't change?