Fixing Warning React and introducing some other bug

In Search component we can see how a debounce() funcition is used. The debounce() function forces a function to wait a certain amount of time before running again. With this function we get that an API call is not made every time we type a letter in the search field. The call is made once the user stops typing.

We also have to check that the first time the page is loaded a search is performed, that is why we check that there are no search results yet to perform this search.

if (term && !results.length) {
search();
}else{
But now, we might notice that if we go back over to our console application and take a look at the console, we have an extra warning inside of here.
React Hook useEffect has a missin dependency: ‘ result.length’
Either include it or remove the dependency array react-hooks/eshaustive-deps

Inside useEffect function we added a piece of state, results.length. Any time we refer to a prop or a piece of state inside of useEffect, React or specifically a rule built into it  (ESLint) wants us to reference any different prop or piece of state inside of useEffect dependency array (the array that controls when useEffect gets executed).

If we add the results.length piece of state to dependency array the warning go away.

There are some scenarios we are going making use of useEffect and not properly listing out all the pieces of states and props inside this array can lead to some really weird and hard to debug problems. So that rule, that warning that we just saw is all about helping you avoid those kind of hard to understand problems that can sometime come up when you’re making use of useEffect.

But, even though that rule is very well intentioned and it does without a doubt solve some other problems that might come up down the road. Just arbitrarily adding in more elements inside this array can also lead to some nasty bugs as well.

Let me show you what the bug is that we just introduced by listing results in dependency array.

When we reload the page, only 1 API call should be executed, but 2 calls are being made.

In the diagram shown below you can clearly see what the problem is.

When loading the page there are no search results (results.length is zero ) and the default call is made, searching with the term ‘programming’. After getting results the value of results.length changes and since this piece of state is in the dependency array, this causes a second call to be made.

To solve this problem we must change the structure of our code. We are going to introduce another piece of state: debouncedTerm and we’re going to set up 2 separates useEffect functions. One is going to watch debouncedTerm(as dependency) and the other is going to watch term (as dependency)

}, [debouncedTerm]);
}, [term]);

This is our final solution.

There are no more warnings or bugs

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published.