How to improve search in React using Debouncing
Debouncing will help you avoid overloading the server and optimize application performance. Below are detailed instructions.
In React, when implementing search functionality, the onChange handler calls the search function each time the user types inside the input box. This method can cause performance errors, especially when making API calls or database queries. Frequent calls to the search function can overload the web server, causing the UI to become unresponsive. Debouncing will solve this problem.
What is Debouncing?
Specifically, you implement a search function in React by calling an onChange handler function on each keystroke as follows:
import { useState } from "react"; export default function Search() { const [searchTerm, setSearchTerm] = useState(""); const handleSearch = () => { console.log("Search for:", searchTerm); }; const handleChange = (e) => { setSearchTerm(e.target.value); // Calls search function handleSearch(); }; return ( ); }
While the above code works, calling the backend to update search results on every keystroke can be expensive. For example, if you are looking for 'webdev', the application will send a query to the backend with the values 'w', 'we', 'web', etc.
Debouncing is a technique that works by delaying the execution of a function until the delay expires. The debounce function detects each keystroke by the user and prevents calls to the search handler until the delay expires. If the user continues typing during the delay, the timer is reset and React calls the function again for the new delay. This process continues until the user stops typing.
By waiting for the user to pause typing, debouncing ensures the application only performs necessary search queries, thereby reducing server load.
How to debounce search in React
There are several libraries you can use to implement debounce. You can also choose to implement it yourself from scratch using the JavaScript setTimeout and clearTimeout functions.
This article uses the debounce function from the lodash library. Assuming you have an existing React project, create a new component named Search. If you don't have an active project yet, create a React app using create-react-app.
In the Search component file, copy the following code to create a search input box that calls the handler function on each keystroke.
import { useState } from "react"; export default function Search() { const [searchTerm, setSearchTerm] = useState(""); const handleSearch = () => { console.log("Search for:", searchTerm); }; const handleChange = (e) => { setSearchTerm(e.target.value); // Calls search function handleSearch(); }; return ( ); }
To debounce the handleSearch function , convert it to the debounce function from lodash.
import debounce from "lodash.debounce"; import { useState } from "react"; export default function Search() { const [searchTerm, setSearchTerm] = useState(""); const handleSearch = () => { console.log("Search for:", searchTerm); }; const debouncedSearch = debounce(handleSearch, 1000); const handleChange = (e) => { setSearchTerm(e.target.value); // Calls search function debouncedSearch(); }; return ( ); }
In the debounce function , you are passing to the function you want to delay, e.g. handleSearch, the delay time is in milliseconds, e.g. 500ms.
While the above code will delay calling the handleSearch query until the user pauses typing, it does not work in React.
Debouncing and Rendering
This application uses input control. That means the state value controls the input value. Each time the user enters the search field, React updates this state.
In React, when the state value is changed, React shows the component and implements all the functions inside it.
In the above search component, when rendering the component again, React runs the debounce function. This function creates a new stopwatch, continuously monitors the delay, and the old stopwatch remains in memory. When the timer expires, it activates the search feature. This means the search function is never debounced, it is delayed by about 500ms. This cycle repeats on each render - the function creates a new timer, the old one expires, then it calls the search function.
For the debounce function to work, you only have to call it once. You can do this by calling the debounce function outside the component or by using mnemonics. This way, even if the component is visible, React won't run it again.
Define the debounce function outside the search component
Move the debounce function outside the search element like below:
import debounce from "lodash.debounce" const handleSearch = (searchTerm) => { console.log("Search for:", searchTerm); }; const debouncedSearch = debounce(handleSearch, 500);
Now in the Search component , call debouncedSearch and pass it the search term.
export default function Search() { const [searchTerm, setSearchTerm] = useState(""); const handleChange = (e) => { setSearchTerm(e.target.value); // Calls search function debouncedSearch(searchTerm); }; return ( ); }
This search function will only be called after the delay period ends.
Memoizing the Debounce function
Memoizing refers to saving the results of a function and reusing them when you call the function with the same arguments.
To memoize the debounce function , use the useMemo hook .
import debounce from "lodash.debounce"; import { useCallback, useMemo, useState } from "react"; export default function Search() { const [searchTerm, setSearchTerm] = useState(""); const handleSearch = useCallback((searchTerm) => { console.log("Search for:", searchTerm); }, []); const debouncedSearch = useMemo(() => { return debounce(handleSearch, 500); }, [handleSearch]); const handleChange = (e) => { setSearchTerm(e.target.value); // Calls search function debouncedSearch(searchTerm); }; return ( ); }
Note that you also wrap the handleSearch function in the useCallback hook to ensure React only calls it once. Without the useCallback hook , React would run the handleSearch function with each re-render, causing the dependencies of the useMemo hook to change, which in turn would call the debounce function .
Now, React will only call the debounce function if handleSearch or the delay changes.
In short, debounce will help programmers reduce queries to the server because it only sends queries after the delay has expired and the user has paused typing. Thanks to that, the server is not overloaded and the application performance is improved.
You should read it
- Best React Usages in 2023
- 6 best free tutorials to learn about React and create web applications
- How to detect clicks outside a React component using a custom hook
- How to use Sass in React
- Instructions for creating a Tic-Tac-Toe game using React-Native
- Tooltip creation tools are useful with ReactJS
- React mistakes to avoid for successful app development
- How to manage state in React using Jotai
- How to speed up React apps with code splitting
- How to create a Hacker News clone using React
- Google wants to help users better access reliable information sources on the internet
- Introduction to ReactJS: Why Should You Use React JS?
Maybe you are interested
Difference between function and formula in Excel
8 little-known Excel functions that can save you a lot of work
How to use the NORMDIST function in Excel - Function that returns the distribution in Excel
Date functions in Excel, DAY, WEEKDAY, MONTH
How to use the SUMIF function in Excel to calculate the sum based on conditions
How to use the Round function in Excel to round numbers and process data