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

135
Visualizações
React - onClick setTimeout/clear old timeout if there is one

I'm doing a toy project where I generate a lot of tints and shades of colors and clicking on them copies their hex values to the clipboard. Originally, I was using an onClick handler on the color article to set my state value alert to true (which would display "copied to clipboard") and using useEffect to set a 3 second timer with setTimeout before turning alert false so that the text would disappear after awhile.

The relevant code inside my Color component:

  useEffect(() => {
    const timeout = setTimeout(() => {
      setAlert(false);
    }, 3000);
    return () => clearTimeout(timeout);
  }, [alert]);

and

  return (
    <article
      className={`color ${index > (list.length - 1) / 2 ? "color-light" : ""}`}
      style={{ backgroundColor: `rgb(${rgbString})` }}
      onClick={() => {
        setAlert(true);
        navigator.clipboard.writeText(hexValue);
      }}
    >
      <p className="percent-value">{weight}%</p>
      <p className="color-value">{rgbToHex(...rgb)}</p>
      {alert && <p className="alert">copied to clipboard</p>}
    </article>
  );

This works, but in the case of multiple clicks on the same color article, I want to have the "copied to clipboard" alert disappear 3 seconds after the last click. In other words, I want multiple clicks to refresh the timer. Currently, it disappears 3 seconds after the first click, so subsequent clicks do not refresh the timer. This is because subsequent clicks on the color don't change the alert state value, so I can't refresh my timer in useEffect. I tried to solve this by calling setAlert(false) before setAlert(true) in my onClick to force the state to change every click and let me enter useEffect by force but this doesn't work. I've also tried different ways of removing useEffect entirely and trying to do everything in the onClick block since it's semantically closer to what I'm trying to do, but I can't figure out how to achieve my result that way. Any pointers?

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

0

What you can do is declare a variable alertTimeout outside of your component:

let alertTimeout;
function MyComponent(props) {
...
}

And in your component you define a function for the timeout triggering/refreshing :

function triggerAlert() {
  if (alertTimeout) {
    clearTimeout(alertTimeout);
  }
  setAlert(true);
  alertTimeout = setTimeout(() => {
    setAlert(false);
  }, 3000);
}

And you call this function with onClick:

onClick={() => {
    triggerAlert();
    navigator.clipboard.writeText(hexValue);
  }}

And you need to add a uesEffect to clear the timeout on component unmount:

useEffect(() => {
  return function cleaning() {
    if (alertTimeout) {
      clearTimeout(alertTimeout);
    }
  }
}, [])
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