Fetching API data with useEffect can be tricky sometimes. In this article, we will look at one trick for efficient data fetching with useEffect.
This article assumes you understand how useEffect hook works. If you do not, visit the react docs.
Let's begin, shall we?
setTimeout
setTimeout is a javascript function that takes in another function or a random code snippet and executes it after a specified period of time(millisecond).
setTimeout(
console.log('You will get this in five seconds egghead.'),
5000)
The setTimeout function will execute the console.log() function after five seconds of running the code.
setTimeout(
function Add(a, b){
return 4+7;
},
3000)
Here, we can see that the setTimeout function can take in another function. The Add function inside setTimeout function in this case runs after three seconds of running the code.
That should very much explain how the setTimeout function works. Let's now look at how we can use it for data fetching with useEffect.
Data fetching in UseEffect
useEffect(() => {
const fetchData = async () => {
await fetch(`https://api.github.com/users/${input}`)
.then((res) => res.json())
.then((res) => setData([res]))
.catch((e) => console.error(e));
};
fetchData();
}, [input]);
As we can see in the code above, A request will be sent to the github API based on what the user types in the input. But there is a problem with this method of requesting data from API, considering the fact that the search value is being typed in by the user. Let me show you!
If you look at the image above very well, you will see that there is a request to the API on every keypress in the network, which is bad. It is bad because multiple requests are being sent to the API and there are multiple responses too. This is caused by the useEffect function which runs on every state change. Remember that state changes whenever there is a keypress and useEffect runs every time there is a change in state. So every time you click on the keyboard, a request is made to the API.
Two other problems with this method are:
It slows down the app due to the too many unnecessary and irrelevant request being made to the API and it is prone to error.
There is always a limit to the number of request a user can make to the API per hour. So this reduces the number of accurate data you can get from API as so many unnecessary request are eating up the specified number of permitted API request.
Well, we obviously do not want that, so will be using setTimeout to solve the problem of multiple request. Let's go!
Solution
The solution to this issue of multiple unnecessary request is very simple. We can solve this by wrapping the fetchData function in a setTimeout function.
useEffect(() => {
const fetchData = async () => {
await fetch(`https://api.github.com/users/${input}`)
.then((res) => res.json())
.then((res) => setData([res]))
.catch((e) => console.error(e));
};
const timer = setTimeout(() => {
fetchData();
}, 5000);
return () => clearTimeout(timer);
}, [input]);
In the code above, the setTimeout function delays any form of request that would have been made to the API after every keypress for five seconds. This gives user enough time to fully type in the search value. The request will be made after five seconds of no keypress. This is actually better, because it does not send multiple request to the API on every keypress.
With setTimeout, we can see that only one request is being made to the API and we get only one accurate response. This simple practice can improve the speed of the app and its performance too as it does not overload the network with multiple irrelevant requests.
With that being said, I want to believe that you will be using setTimeout in your next API call when the request involves an input value, to avoid unnecessary requests and responses. Good Luck!
Top comments (5)
thanks man, appreciate it.
Umm how does the first example work? setTimeout seems to take the return value of console.log, not a function that executes it
Wow, I must have missed that. Thank you for spotting the mistake. I'll make my corrections.
may feel better use debounce
That's a very nice one too, Thank you.