4

I'm trying to debounce an onChange event when a user type in a input field.

I'm referencing these threads:

Perform debounce in React.js

Set input value with a debounced onChange handler

I have the following snippet where I try to replicate the solutions provided in the threads above:

  const handler = useCallback(debounce(setSearchQuery(value), 500), []);

  useEffect(() => {
    document.addEventListener('keydown', handleDocumentKeyDown);
    handler(value);
    return () => document.removeEventListener('keydown', handleDocumentKeyDown);
  }, [isOpen, handleDocumentKeyDown, handler, value]);

  ...

  const handleChange = (event) => {
    setValue(event.target.value);
  };

Error:

Uncaught TypeError: handler is not a function

How can I debounce setSerachQuery() for 500ms while the user is typing in the input field?

norbitrial
  • 14,716
  • 7
  • 32
  • 59
Carrein
  • 3,231
  • 7
  • 36
  • 77

2 Answers2

3

The issue in your case is that instead of passing a function to debounce, you are invoking it directly. You can use arrow function within debounce like

const handler = useCallback(debounce(() => setSearchQuery(value), 500), []);

Full code

const handler = useCallback(debounce(() => setSearchQuery(value), 500), []); // arrow function here

  useEffect(() => {
    document.addEventListener('keydown', handleDocumentKeyDown);
    handler(value);
    return () => document.removeEventListener('keydown', handleDocumentKeyDown);
  }, [isOpen, handleDocumentKeyDown, handler, value]);

  ...

  const handleChange = (event) => {
    setValue(event.target.value);
  };
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • 14
    this gives me the lint error `React Hook useCallback received a function whose dependencies are unknown. Pass an inline function instead.eslintreact-hooks/exhaustive-deps` – Daniel Lizik Feb 24 '21 at 04:36
  • 2
    you could pass setSearchQuery as a dependency to useCallback but since the function doesn't change, you can disable the eslint warning too. Check [this post for more details](https://stackoverflow.com/questions/55840294/how-to-fix-missing-dependency-warning-when-using-useeffect-react-hook/55854902#55854902) – Shubham Khatri Feb 24 '21 at 05:28
  • 2
    You cannot assume the function doesn't change and also disabling eslint warnings is a bad practice if you're working in a team, as you don't want newbie devs to copy this practice, bypassing eslint warning the second they get into difficulties. So, I suggest, spending as much time as possible solving the issues – vsync Aug 08 '22 at 16:22
3

Not pretty at all, but the only way I've managed to do it without dependency problems is:

  const debouncer = useRef(debounce((over: Over | null) => {
    console.log(over);
  }, 100));

  const onOver = useCallback((over: Over | null) => {
    debouncer.current(over);
  }, [debouncer]);
Omar Omeiri
  • 1,506
  • 1
  • 17
  • 33