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

98
Visualizações
useEffect() without a cleanup function

it says that : "Each time that our component renders, our effect is called, adding another event listener. With just a few clicks and re-renders, we have attached a lot of event listeners to the DOM! We need to clean up after ourselves!".

so for every click the count goes from 1 to 3 to 7 instead of incrementing by 1. I don't understand how does so many event listeners got attached and how is this effecting the total count?

import React, { useState, useEffect } from 'react';

export default function Counter() {
  const [clickCount, setClickCount] = useState(0);

  const increment = () => {
    setClickCount(prev => prev + 1);
  };

  useEffect(() => {
    document.addEventListener('mousedown', increment);

  })

  return (
      <h1>Document Clicks: {clickCount}</h1>
  );
}

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

0

You're adding a listener to the document itself, so you need to remove it when component is unmounted.

And you need to add an empty dependency array to not add a new listener on each rerender

And you either need to wrap increment in a useCallback or use a different increment function in the useEffect:

import React, { useState, useEffect } from 'react';

export default function Counter() {
  const [clickCount, setClickCount] = useState(0);

  const increment = useCallback(() => {
    setClickCount(prev => prev + 1);
  }, [setClickCount]);

  useEffect(() => {
    document.addEventListener('mousedown', increment);

    return () => document.removeEventListener('mousedown', increment);
  }, [])

  return (
      <h1>Document Clicks: {clickCount}</h1>
  );
}
about 4 years ago · Juan Pablo Isaza Relatório

0

Without using an array of dependencies, every change will trigger your useEffect to run again.

So every re-render, every changing state will cause you to create another eventListener.

Let's talk about variant useEffect:

useEffect(() => {
  // invoking on every re-render
})
useEffect(() => {
  // invoking on component did mount (once)
}, [])
useEffect(() => {
  // invoking on component did mount and with every change on counter
}, [counter])

Also, you need to remove your eventLinstener on the component unmount:

 useEffect(() => {
    document.addEventListener('mousedown', increment);

    return () => document.removeEventListener('mousedown', increment);

  }, [])

Optional

As mentioned with Samathingamajig in the answers, you can use an optimized way to define your increment function with useCallback.

With the current implementation, your increment method will be re-defined every time (with every change and re-render) but using useCallback it will be redefined only when the useCallback's array of dependencies got changes.

import React, {useEffect, useCallback} from 'react';

// rest of the codes ...

  const increment = useCallback(() => {
    setClickCount(prevState => prevState + 1);
  }, [setClickCount]);
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