Skip to content

[BUG] useDebounceCallback doesn't seem to memoize the callback function #656

@marcebdev

Description

@marcebdev

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:

  1. a stronger example is needed, as we can see useState is basically cheating
  2. improve tests as critical test cases are missed
  3. fix bug (it is not a useCallback variant 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions