Security News
The Unpaid Backbone of Open Source: Solo Maintainers Face Increasing Security Demands
Solo open source maintainers face burnout and security challenges, with 60% unpaid and 60% considering quitting.
use-debounce
Advanced tools
The use-debounce package provides a collection of hooks and functions to debounce any fast-changing value in React applications. The main purpose is to limit the rate at which a function gets invoked. This is particularly useful for performance optimization in scenarios such as search input fields, where you might want to wait for a pause in typing before sending a request to a server.
useDebounce
This hook allows you to debounce any fast-changing value. The first parameter is the value to debounce, and the second parameter is the delay in milliseconds.
import { useDebounce } from 'use-debounce';
const [value] = useDebounce(text, 1000);
useDebouncedCallback
This hook gives you a debounced function that you can call. It will only invoke the provided function after the specified delay has elapsed since the last call.
import { useDebouncedCallback } from 'use-debounce';
const [debouncedCallback] = useDebouncedCallback(
() => {
// function to be debounced
},
1000
);
useThrottledCallback
Similar to debouncing, throttling is another rate-limiting technique. This hook provides a throttled function that will only allow one execution per specified time frame.
import { useThrottledCallback } from 'use-debounce';
const [throttledCallback] = useThrottledCallback(
() => {
// function to be throttled
},
1000
);
lodash.debounce is a method from the popular Lodash library. It provides debouncing functionality similar to use-debounce but is not a hook and does not have React-specific optimizations.
debounce is a minimalistic package that offers a debounce function. It is not tailored for React and does not provide hooks, but it can be used in any JavaScript application.
react-throttle offers components and hooks to throttle events or values in React applications. It is similar to use-debounce's throttling capabilities but focuses specifically on throttling rather than debouncing.
It provides:
Install it with yarn:
yarn add use-debounce
Or with npm:
npm i use-debounce --save
The simplest way to start playing around with use-debounce is with this CodeSandbox snippet: https://codesandbox.io/s/kx75xzyrq7
More complex example with searching for matching countries using debounced input: https://codesandbox.io/s/rr40wnropq (thanks to https://twitter.com/ZephDavies)
According to https://twitter.com/dan_abramov/status/1060729512227467264
import React, { useState } from 'react';
import { useDebounce } from 'use-debounce';
export default function Input() {
const [text, setText] = useState('Hello');
const [value] = useDebounce(text, 1000);
return (
<div>
<input
defaultValue={'Hello'}
onChange={(e) => {
setText(e.target.value);
}}
/>
<p>Actual value: {text}</p>
<p>Debounce value: {value}</p>
</div>
);
}
This hook compares prev and next value using shallow equal. It means, setting an object {}
will trigger debounce timer. If you have to compare objects (https://github.com/xnimorz/use-debounce/issues/27#issuecomment-496828063), you can use useDebouncedCallback
, that is explained below:
Besides useDebounce
for values you can debounce callbacks, that is the more commonly understood kind of debouncing.
Example with Input (and react callbacks): https://codesandbox.io/s/x0jvqrwyq
import { useDebouncedCallback } from 'use-debounce';
function Input({ defaultValue }) {
const [value, setValue] = useState(defaultValue);
// Debounce callback
const [debouncedCallback] = useDebouncedCallback(
// function
(value) => {
setValue(value);
},
// delay in ms
1000
);
// you should use `e => debouncedCallback(e.target.value)` as react works with synthetic evens
return (
<div>
<input defaultValue={defaultValue} onChange={(e) => debouncedCallback(e.target.value)} />
<p>Debounced value: {value}</p>
</div>
);
}
Example with Scroll (and native event listeners): https://codesandbox.io/s/32yqlyo815
function ScrolledComponent() {
// just a counter to show, that there are no any unnessesary updates
const updatedCount = useRef(0);
updatedCount.current++;
const [position, setPosition] = useState(window.pageYOffset);
// Debounce callback
const [scrollHandler] = useDebouncedCallback(
// function
() => {
setPosition(window.pageYOffset);
},
// delay in ms
800
);
useEffect(() => {
const unsubscribe = subscribe(window, 'scroll', scrollHandler);
return () => {
unsubscribe();
};
}, []);
return (
<div style={{ height: 10000 }}>
<div style={{ position: 'fixed', top: 0, left: 0 }}>
<p>Debounced top position: {position}</p>
<p>Component rerendered {updatedCount.current} times</p>
</div>
</div>
);
}
useDebounce
and useDebouncedCallback
works with maxWait
option. This params describes the maximum time func is allowed to be delayed before it's invoked.cancel
callbackThe full example you can see here https://codesandbox.io/s/4wvmp1xlw4
import React, { useState, useCallback } from 'react';
import ReactDOM from 'react-dom';
import { useDebouncedCallback } from 'use-debounce';
function Input({ defaultValue }) {
const [value, setValue] = useState(defaultValue);
const [debouncedFunction, cancel] = useDebouncedCallback(
(value) => {
setValue(value);
},
500,
// The maximum time func is allowed to be delayed before it's invoked:
{ maxWait: 2000 }
);
// you should use `e => debouncedFunction(e.target.value)` as react works with synthetic evens
return (
<div>
<input defaultValue={defaultValue} onChange={(e) => debouncedFunction(e.target.value)} />
<p>Debounced value: {value}</p>
<button onClick={cancel}>Cancel Debounce cycle</button>
</div>
);
}
const rootElement = document.getElementById('root');
ReactDOM.render(<Input defaultValue="Hello world" />, rootElement);
useDebouncedCallback
has callPending
method. It allows to call the callback manually if it hasn't fired yet. This method is handy to use when the user takes an action that would cause the component to unmount, but you need to execute the callback.
import React, { useState, useCallback } from 'react';
import { useDebouncedCallback } from 'use-debounce';
function InputWhichFetchesSomeData({ defaultValue, asyncFetchData }) {
const [debouncedFunction, cancel, callPending] = useDebouncedCallback(
(value) => {
asyncFetchData;
},
500,
{ maxWait: 2000 }
);
// When the component goes to be unmounted, we will fetch data if the input has changed.
useEffect(
() => () => {
callPending();
},
[callPending]
);
return <input defaultValue={defaultValue} onChange={(e) => debouncedFunction(e.target.value)} />;
}
Both useDebounce
and useDebouncedCallback
work with the leading
option. This param will execute the function once immediately when called. Subsequent calls will be debounced until the timeout expires.
For more information on how leading debounce calls work see: https://lodash.com/docs/#debounce
import React, { useState } from 'react';
import { useDebounce } from 'use-debounce';
export default function Input() {
const [text, setText] = useState('Hello');
const [value] = useDebounce(text, 1000, { leading: true });
// value is updated immediately when text changes the first time,
// but all subsequent changes are debounced.
return (
<div>
<input
defaultValue={'Hello'}
onChange={(e) => {
setText(e.target.value);
}}
/>
<p>Actual value: {text}</p>
<p>Debounce value: {value}</p>
</div>
);
}
You can provide additional options as a third argument to both useDebounce
and useDebouncedCallback
:
option | default | Description | Example |
---|---|---|---|
maxWait | - | Describes the maximum time func is allowed to be delayed before it's invoked | https://github.com/xnimorz/use-debounce#cancel-maxwait-and-memoization |
leading | - | This param will execute the function once immediately when called. Subsequent calls will be debounced until the timeout expires. | https://github.com/xnimorz/use-debounce#leading-calls |
equalityFn | (prev, next) => prev === next | Comparator function which shows if timeout should be started |
4.0.0
useDebouncedCallback(callback, 300, {
leading: true,
trailing: false,
maxWait: 300,
});
Where the trailing edge is turned off. Let's say the function is called twice in the first 300ms. Now debounced function to have been called once.
how to migrate: Please, check your traling: false
params with maxWait
option
breaking change: Now in case delay option is unset, it will be requestAnimationFrame
delay
breaking change: Now debouncedCallback
from useDebouncedCallback
returns a value. In v3 it used to return undefined
:
FAQs
Debounce hook for react
The npm package use-debounce receives a total of 1,176,536 weekly downloads. As such, use-debounce popularity was classified as popular.
We found that use-debounce demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Solo open source maintainers face burnout and security challenges, with 60% unpaid and 60% considering quitting.
Security News
License exceptions modify the terms of open source licenses, impacting how software can be used, modified, and distributed. Developers should be aware of the legal implications of these exceptions.
Security News
A developer is accusing Tencent of violating the GPL by modifying a Python utility and changing its license to BSD, highlighting the importance of copyleft compliance.