Optimizing React Applications with Custom Debounce Hooks
What is Debouncing?
Debouncing is a technique used to optimize the execution of expensive functions by delaying their execution for a certain period. This technique is particularly useful when dealing with user input, such as keystroke listeners or resizing events, where multiple calls to the server can be made in rapid succession.
Creating a Custom Debounce Hook
To create a custom debounce hook, we will use the useState
and useEffect
hooks provided by React. Our hook will take two parameters: the value to be debounced and the delay time.
import { useState, useEffect } from 'eact';
const useDebounce = (value, delay) => {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timerId = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => clearTimeout(timerId);
}, [value, delay]);
return debouncedValue;
};
Our hook uses the useState
hook to store the debounced value and the useEffect
hook to update the debounced value after the specified delay. The useEffect
hook also returns a cleanup function to clear the timeout when the component is unmounted.
Improving the Debounce Hook
While our custom debounce hook works well, it can be improved by using the AbortController
API to cancel ongoing requests. This is particularly useful when dealing with network traffic and optimization techniques.
import { useState, useEffect } from 'eact';
import { AbortController } from 'abort-controller';
const useDebounce = (value, delay) => {
const [debouncedValue, setDebouncedValue] = useState(value);
const controller = new AbortController();
useEffect(() => {
const timerId = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(timerId);
controller.abort();
};
}, [value, delay]);
return debouncedValue;
};
By using the AbortController
API, we can cancel ongoing requests when the component is unmounted or when the user input changes.
Using the Custom Debounce Hook
To use our custom debounce hook, we simply need to import it and pass the value and delay time as parameters.
import React, { useState } from 'eact';
import useDebounce from './useDebounce';
const SearchInput = () => {
const [searchQuery, setSearchQuery] = useState('');
const debouncedSearchQuery = useDebounce(searchQuery, 500);
const handleSearch = async () => {
const response = await fetch(
undefined.example.com/search?q=${debouncedSearchQuery}
);
const data = await response.json();
console.log(data);
};
return (
<div>
<input
type="text"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
placeholder="Search..."
/>
<button onClick={handleSearch}>Search</button>
</div>
);
};
In this example, we use our custom debounce hook to debounce the search query input by 500ms. When the user types in the search input field, the handleSearch
function is called after the debounced delay, which makes an API call to the server with the debounced search query.