Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
131 lines (97 sloc) 3.67 KB

useThrottledFn

Accepts a function and returns a new memoized version of that function that waits the defined time before allowing the next execution. 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, useThrottledFn } from 'beautiful-react-hooks'; 

const ThrottledFnComponent = () => {
   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 = useThrottledFn(() => {
     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>
   );
};

<ThrottledFnComponent />

Options

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

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

const ThrottledFnComponent = () => {
   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 = useThrottledFn(() => {
     setWidth(window.innerWidth);
     setHeight(window.innerHeight);
   }, 500, options);
   
   useWindowResize(onWindowResizeHandler);
      
   return (
     <DisplayDemo>
       <p>window width: {width}</p>
       <p>window height: {height}</p>
     </DisplayDemo>
   );
};

<ThrottledFnComponent />

Dependencies

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

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

const ThrottledFnComponent = (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 = useThrottledFn(() => {
     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>
   );
};

<ThrottledFnComponent 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.