DEV Community

Cover image for Optimizing User Experience with useDebounce() Hook
Shaan Alam
Shaan Alam

Posted on

Optimizing User Experience with useDebounce() Hook

Optimizing User experience is one of the key elements in Web Development. One aspect of improving the user experience is debouncing

What is debouncing?

Debouncing in simple terms is just delaying a function to make sure that it doesn’t get called too often which can lead to performance issues. You might wanna ask, why’d we want to delay the function?

Nice Question!

The answer is what if the function uses heavy resources in our software? We cannot afford it to get called too often. For example, if the function is calling an API we wouldn’t wanna call it too many times.

Real world Example

Suppose we are creating a live search features where whenever user types the name of a product, the list updates in real-time. Now, let’s suppose for every key stroke that user makes an API is getting called.

Suppose the user is searching for MacBook Air . In this case 11 subsequent API requests (for each character) will be made to the server, which can increase server load and cause performance issues.

Server Load

Solution

The Solution is debouncing the function. Which means that we will add a delay to the function to make sure the user has finished typing. And if the user types again we will just cancel the previous call and call the function again when the user finishes.

In this tutorial we’re gonna create a useDebounce() hook for this purpose.

import { useEffect, useState } from 'react'

export function useDebounce<T>(value: T, delay?: number): T {
  const [debouncedValue, setDebouncedValue] = useState<T>(value)

  useEffect(() => {
    const timer = setTimeout(() => setDebouncedValue(value), delay || 500)

    return () => {
      clearTimeout(timer)
    }
  }, [value, delay])

  return debouncedValue
}
Enter fullscreen mode Exit fullscreen mode

Now, let's dive deeper into the live search example we've discussed earlier. As mentioned before, the hook will update the value of debouncedValue state every delay milliseconds. This means that every time the user types a character, the hook waits for delay milliseconds before updating the debouncedValue. If during that duration the value passed is changed, the previous timeout is cleared and a new timeout is set. This ensures that the hook only returns the final value after the user has stopped typing for at least delay milliseconds. Once the timeout is over, the debouncedValue is changed to the final value. This way, we can avoid unnecessary API calls or other expensive operations that would slow down the user interface.

Usage of the hook

export default function Component() {
  const [value, setValue] = useState<string>('')
  const debouncedValue = useDebounce<string>(value, 500)

  const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
    setValue(event.target.value)
  }

  // Fetch API (optional)
  useEffect(() => {
    // Do fetch here...
    // Triggers when "debouncedValue" changes
  }, [debouncedValue])

  return (
    <div>
      <p>Value real-time: {value}</p>
      <p>Debounced value: {debouncedValue}</p>

      <input type="text" value={value} onChange={handleChange} />
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Resources

https://usehooks-ts.com/react-hook/use-debounce

Conclusion

I hope you enjoyed this tutorial. If you think I made a mistake somewhere let me know in the comment section.

My Socials

Twitter - https://twitter.com/shaancodes

Instagram - https://www.instagram.com/shaancodes/

GitHub - https://github.com/shaan-alam/

Top comments (0)