[BUG] useDebounceCallback doesn't seem to memoize the callback function
Author: marcebdevCreated Nov 13, 2024Updated Oct 22, 2025
Labelsbug
Describe the bug
Debounce is called multiple times if you use a non-memoized function, like an inline arrow function or something you'd typically put into a useCallback (so not passing a setState or similar directly).
Using a custom arrow function like you'd use in useCallback or something similar is not uncommon nor unresonable. Many other libraries show better examples (than passing a useState directly) and use something like this as an example e.g. https://mantine.dev/hooks/use-debounced-callback/
So the issues are many fold:
- a stronger example is needed, as we can see
useStateis basically cheating - improve tests as critical test cases are missed
- fix bug (it is not a
useCallbackvariant hook without this fix)
To Reproduce
const Test = () => {
const [value, setValue] = useState<string>('')
const [, setDebouncedValue] = useState('')
const debounce = useDebounceCallback((val: string) => {
console.log('debounced', val)
if (value) setDebouncedValue(val)
}, 1500)
return (
<input
value={value}
onChange={({ target: { value } }) => {
setValue(value)
debounce(value)
}}
/>
)
}Expected behavior
debounced functions should be called once
Right now that console will print the following if "123" is typed
debounced 1 debounced 12 debounced 123
Additional context
No response
Source: juliencrn/usehooks-ts