Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
2 contributors

Users who have contributed to this file

@antonioru @ayarushin
132 lines (97 sloc) 3.73 KB

useDebouncedFn

Accepts a func and returns a new memoized version of that function that delays invoking func until after the defined time have elapsed since the last time the debounced function was invoked.

If time is not defined, its default value will be 100ms.

Why? πŸ’‘

  • To control how many times we allow a function to be executed over time regardless the number of renders the component is performing
  • when we attaching listeners to a DOM event.

Basic Usage

import { useEffect, useState } from 'react'; 
import { useWindowResize, useDebouncedFn } from 'beautiful-react-hooks'; 

const DebouncedFnComponent = () => {
   const [width, setWidth] = useState(window.innerWidth);
   const [height, setHeight] = useState(window.innerHeight);
   
   // there's no need to use `useCallback` since the returned function 
   // is already memoized
   const onWindowResizeHandler = useDebouncedFn(() => {
     setWidth(window.innerWidth);
     setHeight(window.innerHeight);
   }, 250);
   
   useWindowResize(onWindowResizeHandler);
   useEffect(() => {
     // do something
     // don't forget to cancel debounced
     return () => onWindowResizeHandler.cancel(); // or .flush()
   });
      
   return (
     <DisplayDemo>
       <p>window width: {width}</p>
       <p>window height: {height}</p>
     </DisplayDemo>
   );
};

<DebouncedFnComponent />

Options

Since useDebouncedFn uses lodash.throttle under the hood, you can possibly define few options to customise its behaviour.

import { useState } from 'react'; 
import { useWindowResize, useDebouncedFn } from 'beautiful-react-hooks'; 

const DebouncedFnComponent = () => {
   const [width, setWidth] = useState(window.innerWidth);
   const [height, setHeight] = useState(window.innerHeight);
   const options = {
     leading: false,
     trailing: true,
   };
   
   // there's no need to use `useCallback` since the returned function 
   // is already memoized
   const onWindowResizeHandler = useDebouncedFn(() => {
     setWidth(window.innerWidth);
     setHeight(window.innerHeight);
   }, 500, options);
   
   useWindowResize(onWindowResizeHandler);
      
   return (
     <DisplayDemo>
       <p>window width: {width}</p>
       <p>window height: {height}</p>
     </DisplayDemo>
   );
};

<DebouncedFnComponent />

Dependencies

Since useDebouncedFn uses useCallback under the hood, you can possibly define the callback dependencies.

import { useState } from 'react'; 
import { useWindowResize, useDebouncedFn } from 'beautiful-react-hooks'; 

const DebouncedFnComponent = (props) => {
   const [width, setWidth] = useState(window.innerWidth);
   const [height, setHeight] = useState(window.innerHeight);
   
   
   // there's no need to use `useCallback` since the returned function 
   // is already memoized
   const onWindowResizeHandler = useDebouncedFn(() => {
     setWidth(window.innerWidth);
     setHeight(window.innerHeight);
   }, 500, null, [props.foo]);
   
   useWindowResize(onWindowResizeHandler);
      
   return (
     <DisplayDemo>
       <p>window width: {width}</p>
       <p>window height: {height}</p>
     </DisplayDemo>
   );
};

<DebouncedFnComponent foo="bar" />

βœ… Pro tip:

To deep understanding the differences between throttle and debounce, what they are and when to use this functions please read "Debouncing and Throttling Explained Through Examples" by David Corbacho

Mastering the hook

βœ… When to use

  • When in need to control how many times we allow a function to be executed over time
You can’t perform that action at this time.