Tuesday, November 7, 2023

Debounce in Javascript and React

    Debounce is a technique used to improve the performance of frequently executed actions, by delaying them, grouping them, and only executing the last call.

    Imagine, Say for example, You need a search input that automatically queries results as you type.

     You don't want to call the backend or API's with every keystroke, instead you only observe the final value. This is the perfect use for the debounce function, and in fact, it's the most common one.

Define basic debounce function with Javascript

Debounce is implemented using a timer, where the action executes only after the timeout. If the action is repeated before the timer has expires, we restart the timer. 

 

function debounce(func, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}

  In the debounce function:

  • func is the original function you want to debounce.
  • delay is the time in milliseconds that you want to wait after the last call before invoking the original function. 

Implement the debounce function 

    Create a function that accepts a function to debounce and the timeout delay as arguments.


const updateOptions = debounce(query => {
fetch(`https://dummyjson.com/products/search?q=${query}`)
.then(res => res.json())
.then(data => setOptions(data))
}, 1000)
input.addEventListener("input", e => {
updateOptions(e.target.value)
)}

Implement the debounce function with React


export default function SearchBox() {
const [search, setSearch] = React.useState("");
const [result, setResult] = React.useState([]);
const handleChange = (e) => {
setSearch(e.target.value);
};

let timeout;

const handleSearch = async (query) => {
setResult([]);
if (query.length < 3) {
return null;
}
const response = await fetch(
`https://dummyjson.com/products/search?q=${query}`
);
const { products } = await response.json();
setResult(products);
};

React.useEffect(() => {
clearTimeout(timeout);
timeout = setTimeout(() => {
handleSearch(search);
}, 500);
return () => clearTimeout(timeout);
}, [search]);

return (
<>
<div className="mb-3 m-11">
<div className="relative mb-4 flex w-full flex-wrap items-stretch">
<form>
<label
htmlFor="default-search"
className="mb-2 text-sm font-medium text-gray-900 
sr-only dark:text-white"
>
Search
</label>
<div className="relative">
<div className="absolute inset-y-0 left-0 flex items-center 
pl-3 pointer-events-none">
<svg
className="w-4 h-4 text-gray-500 dark:text-gray-400"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 20 20"
>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"
/>
</svg>
</div>
<input
type="search"
id="default-search"
className="block w-full p-4 pl-10 text-sm text-gray-900
 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 
focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 
dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 
dark:focus:border-blue-500"
placeholder="Search Mockups, Logos..."
value={search}
onChange={handleChange}
/>
</div>
</form>
</div>
</div>

<div className="mb-3 m-11">
{result.map((item) => (
<div className="text-xl">{item.title}</div>
))}
</div>
</>
);
}


the  useEffect runs every time the input value changes, after which there is a delay of 500 milliseconds, then the value result is updated with search value.

The Result will be 


 

Happy Coding...😀

No comments:

Post a Comment