Today I am going to show you how to create a useDebounce hook that allows you to super-simply postpone API calls so that they do not happen too often.
I also created a demo that uses our hook. It searches for Marvel Comics APIs and the useDebounce hook allows you to avoid server calls for every keystroke.

Pretty elegant, huh? Ok, now let's get to the code!
, , . , , , . useEffect, , . useState useEffect, .
import React, { useState, useEffect } from 'react';
import useDebounce from './use-debounce';
function App() {
const [searchTerm, setSearchTerm] = useState('');
const [results, setResults] = useState([]);
const [isSearching, setIsSearching] = useState(false);
const debouncedSearchTerm = useDebounce(searchTerm, 500);
useEffect(
() => {
if (debouncedSearchTerm) {
setIsSearching(true);
searchCharacters(debouncedSearchTerm).then(results => {
setIsSearching(false);
setResults(results);
});
} else {
setResults([]);
}
},
[debouncedSearchTerm]
);
return (
<div>
<input
placeholder="Search Marvel Comics"
onChange={e => setSearchTerm(e.target.value)}
/>
{isSearching && <div>Searching ...</div>}
{results.map(result => (
<div key={result.id}>
<h4>{result.title}</h4>
<img
src={`${result.thumbnail.path}/portrait_incredible.${
result.thumbnail.extension
}`}
/>
</div>
))}
</div>
);
}
function searchCharacters(search) {
const apiKey = 'f9dfb1e8d466d36c27850bedd2047687';
const queryString `apikey=${apiKey}&titleStartsWith=${search}`;
return fetch(
`https://gateway.marvel.com/v1/public/comics?${queryString}`,
{
method: 'GET'
}
)
.then(r => r.json())
.then(r => r.data.results)
.catch(error => {
console.error(error);
return [];
});
}
, ! , .
import React, { useState, useEffect } from 'react';
export default function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(
() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(handler);
};
},
[value]
);
return debouncedValue;
}
And here he is in front of you! We now have a hook for deferred values ββwith which we can delay the change of any value directly in the body of our component. The deferred value can then be added to the useEffect dependency array, instead of the mutable values ββthemselves, to limit the frequency of calls to the desired effect.
Here is the Marvel Comic Search demo demo on CodeSandbox.
If you liked it, you can check out and rate my blog about React hooks and the React app builder.