Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

138
Visualizações
Debouncing in react is not working if I directly call the function containing logic for setTimeout

I was trying to implement the debounce functionality in React inside useEffect. Although for the below code, if I call debounceFunc its executing only once whereas if I directly call the debounceFunc3 its not working.

const handleClick = () => {
    setEvent((pre) => [...pre, 1]);
  };
  const delayFunc = () => {
    let timer;
    return function () {
      clearTimeout(timer);
      timer = setTimeout(() => console.log("Hello timer 1"), 2000);
    };
  };

  const delayFunc3 = useCallback(() => {
    let timer3;
    return function () {
      clearTimeout(timer3);
      timer3 = setTimeout(() => console.log("Hello timeout3"), 2000);
    };
  }, []);

  const debounce = useCallback(delayFunc(), []);

  useEffect(() => {
    if (event?.length > 0) {
      debounce();
      delayFunc3()();
    }
  }, [event]); 

In console Hello timer 1 is printed only once whereas Hello timeout3 is printed or each event triggered/changed.

Codebox link to play around:

https://codesandbox.io/s/inspiring-lamport-sbbup?file=/src/App.js:0-872

Couldn't understand what's wring with the way I am calling debounceFunc3

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

The problem with your code is that you're executing delayFunc3() multiple times:

delayFunc3()();

The issue with this is that every time you call delayFunc3()() you're creating a new local timer3 variable within your delayFunc3 function, and then executing the returned function that now references that new local timer3 variable.

This means that if you call delayFunc3()();, first a new timer3 variable is created, and then the returned function is executed, queueing a new timeout.

If you then call delayFunc3()();, again, a new timer3 variable is created (initialized to undefined), and then your returned function is executed. When your returned function is executed you're runnning clearTimeout(timer3);, which won't be clearing any timer as timer3 here is referring to the new timer3 variable that was initialized and is undefined, and not the previous timer3 that was created in the previous function delayFunc3()() call.

As a result, calling delayFunc3()(); again while your first timeout is still running won't have any effect on the first timeout as the timer3 created by this invocation has no relation to the previous timer3 created, and so it won't be cleared.

Unlike this, performing the following:

const debounce = useCallback(delayFunc(), []);

executes your delayFunc() and creates a new local variable timer within the scope of delayFunc(). The returned function from delayFunc() closes over the timer variable declared within the delayFunc() scope. This means that whenever debounce() is executed, you won't be creating a new timer variable like you were in your first example, but instead, you will be reusing the timer created from the initial delayFunc() call. Each call to debounce() will reuse the same timer variable, and so, if debounce() is called again, the clearTimeout(timer); will clear the previously queued timer.


Also note that in both of your examples, you're using useCallback() on two different things. With debounce, you're calling useCallback() on the returned function from delayFunc(). This means that all future rerenders of your component will use the one function reference that was returned from the initial delayFunc() call when your component mounted. So debounce refers to the one unique function for all rerenders.

Unlike this, delayFunc3 is using useCallback() not on the returned function, but rather the entire function (ie: the "parent" arrow function). This means that each rerender of your component will use the same "parent" function, but that parent function still creates a new timer3 variable when invoked and returns a new inner function each time it is called.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda