In the case where we want to build a React search box, or autocomplete text input, a debounce functionality comes very handy as we don't want to have an API called for each keystroke of the user.
So, instead of having something like this:
useEffect(() => {
doApiCall(query)
}, [query]);
We want to have something like this:
useEffect(() => {
(doApiCall(query)
}, [waitForTheTypingToStop(query)]);
In this example, we will use the debounce function from lodash
, but if you want to add your own I've written a post on how to make a debouncing function in Javascript.
Below is the full code of the solution:
const App = ({wait}) => {
const [query, setQuery] = useState("abc");
const ref = useRef();
const onChange = () => console.log("query = ", query)
useEffect(() => {
ref.current = onChange
}, [onChange]);
const doCallbackWithDebounce = useMemo(() => {
const callback = () => ref.current?.()
return lodash.debounce(callback, wait);
}, []);
return (<>
<p>Input debounced for {wait} ms:</p>
<input
value={query}
onChange={(e) => {
doCallbackWithDebounce();
setQuery(e.target.value);
}}
/>
</>);
}
It will debounce the action previously used in useEffect()
for a given number of milliseconds thus limiting the number of API calls:
You can checkout the full working codepen here.
📖 50 Javascript, React and NextJs Projects
Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects with project briefs and wireframes! Choose from 8 project categories and get started right away.
📖 50 Javascript, React and NextJs Projects
Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects with project briefs and wireframes! Choose from 8 project categories and get started right away.