Lets build a Throttle hook in React
2 min read
Whenever we search in a web app, we often don’t send the query to the backend immediately. The query will change with every keystroke, and by sending a request for every keypress, we will send a lot of unnecessary requests, that will eventually just be thrown away whenever they arrive to the frontend because the will be invalid with a new keystroke.
That is why we often implement the debouncing functionality. That will work as a temporarily cached, and if the user has not entered a key in a certain amount of time, the request is send. With that functionality, the user kan keep entering and deleting the query in the frontend, and eventually they will will stop pressing a key, and then the request is sent.
The downside is, that the user will not see any value in the meantime, and will have to wait for the final keystroke.
Throttling to the rescue!
Throttling is another technique that will detect if the user has entered a query, and will keep adding up the latest value until the time has passed, and then it will send a request to the backend. It will then keep sending a request to the backend in a specified interval, until the user has stopped entered any value. After that it will send a last request, if the last query was not send to the backend. With that functionality, we can keep requesting the backend eg. every 500 millisecond, and show data to the user for quicker user response.
Here is the hook
We use useRef to store the values, and then we detect if the prop ‘query’ has changed in the useEffect. If that is the case, we update nextVal ref with the new value. We also check if we have any new value, and if so we start another setTimeout again. With that, we can keep throttling until we don’t have any more values. Last we return the updated value.
This is a basic version of the throttle, and can be refactored so that we can customise how many milliseconds the throttling should last before executing. We could also make the input field more generic instead of just a query of type string. But for now, this does the job i need :-)
You can find the sourcecode here