JavaScript Reference Trap: Fixing API Calls with useMemo

🚀 My API call was firing 4 times… I only wrote it once. I saw 4 API calls in the network tab. I knew it was my code. I just couldn't figure out why. I had this in my code: useEffect(() => { fetchUserData(); }, [user, filters, page, search]); Looks fine, right? The problem — every time the parent re-rendered, it was passing a new object reference for filters. Even though the values were the same. JavaScript doesn't compare objects by value. { page: 1 } === { page: 1 } is false. So, React saw a "new" dependency every single render. And fired the effect. Again. And again. And again. The fix? Either memoize the object with useMemo — or move it outside the component if it's static. const filters = useMemo(() => ({ category: 'all' }), []); 4 API calls became 1. The bug wasn't in the API. It was in how I understood JavaScript references. 2 years in, and I still fall for JavaScript's reference trap sometimes. So, useMemo is not only about computation cost, it's also about referential stability. If it happened to me, it's happening to you too. Save this. You'll need it. ♻️ Repost if this helped someone on your team. #ReactJS #JavaScript #FrontendDevelopment #WebDevelopment #React #Programming

For data fetching, it is always better to avoid useEffect and use react-query or with gql operations use apollo hooks

The real catch here is the deps array inside useMemo. If you pass an object into useMemo's deps without handling it carefully, you aren't fixing the bug—you're just moving it. If the obj in your deps array changes its reference on every render, useMemo will keep recalculating anyway. You'll end up stuck in the exact same loop of re-renders as the original useEffect. Stability only works if the entire chain is stable!

Like
Reply

Javascript checks the object reference, and it re-renders the function again.

Well .. this is a classic JavaScript gotcha that I too had experienced. Referential equality concept of JavaScript with objects in hooks like useEffect often leads to repeated calls when dependencies are recreated on each render .

See more comments

To view or add a comment, sign in

Explore content categories