Skip to content
question

Por que meu useEffect está rodando duas vezes? (e o fetch também)

Larissa Souza@lari_codando

October 12, 2026 · 1 min read

Boa noite, pessoal! Estou fazendo um projeto de portfólio (uma lista de filmes consumindo uma API pública) e notei uma coisa estranha: o console.log dentro do useEffect aparece duas vezes, e na aba Network o fetch também é feito duas vezes.

useEffect(() => {
  console.log('buscando filmes')
  fetch('https://api.exemplo.com/filmes?pagina=' + pagina)
    .then(res => res.json())
    .then(dados => setFilmes(dados.resultados))
}, [pagina])

O array de dependências só tem pagina, e eu não mudo a página ao carregar. Já conferi:

  • que o componente não está sendo renderizado duas vezes no App (só tem um <ListaFilmes />)
  • que não existe outro useEffect fazendo a mesma coisa
  • li a parte de dependências na documentação, mas não achei nada sobre isso

Uai, o que estou fazendo de errado? Isso vai acontecer em produção também? Obrigada desde já! 💛

Accepted answer

Caio Nascimento#1 in Dev Brasil2 likes

Boa noite, Lari! Você não está fazendo nada errado, uai kkkk. Isso é o React.StrictMode. Olha teu main.jsx (ou index.js): deve ter o <App /> dentro de <React.StrictMode>. Em desenvolvimento, o StrictMode monta o componente, desmonta e monta de novo, de propósito, pra te ajudar a achar efeitos que não fazem limpeza direito. Por isso o log aparece duas vezes. Em produção (npm run build) isso NÃO acontece, roda uma vez só. Não tira o StrictMode, ele é teu amigo. O que vale a pena é colocar a limpeza no efeito, porque se o usuário trocar de página rápido a resposta antiga pode chegar depois da nova e sobrescrever: useEffect(() => { const controller = new AbortController() fetch(url, { signal: controller.signal }) .then(res => res.json()) .then(dados => setFilmes(dados.resultados)) .catch(err => { if (err.name !== 'AbortError') console.error(err) }) return () => controller.abort() }, [pagina]) Com isso, na segunda montagem do StrictMode a primeira requisição é cancelada, e você vai ver uma delas como (canceled) na aba Network. Faz sentido? Qualquer coisa me chama.

View in the thread

Get the best of #dev_brasil weekly

One email each Monday with the most useful posts. No spam; unsubscribe in one click.

Comments

6

Sign in to join the conversation.

Sign in to comment

Accepted answer

Caio Nascimento@caio_backend#1 in Dev Brasil
Boa noite, Lari! Você não está fazendo nada errado, uai kkkk. Isso é o React.StrictMode. Olha teu main.jsx (ou index.js): deve ter o <App /> dentro de <React.StrictMode>. Em desenvolvimento, o StrictMode monta o componente, desmonta e monta de novo, de propósito, pra te ajudar a achar efeitos que não fazem limpeza direito. Por isso o log aparece duas vezes. Em produção (npm run build) isso NÃO acontece, roda uma vez só. Não tira o StrictMode, ele é teu amigo. O que vale a pena é colocar a limpeza no efeito, porque se o usuário trocar de página rápido a resposta antiga pode chegar depois da nova e sobrescrever: useEffect(() => { const controller = new AbortController() fetch(url, { signal: controller.signal }) .then(res => res.json()) .then(dados => setFilmes(dados.resultados)) .catch(err => { if (err.name !== 'AbortError') console.error(err) }) return () => controller.abort() }, [pagina]) Com isso, na segunda montagem do StrictMode a primeira requisição é cancelada, e você vai ver uma delas como (canceled) na aba Network. Faz sentido? Qualquer coisa me chama.
2 net votes
Larissa Souza@lari_codando#3 in Dev Brasil
Nó, Caio! Era exatamente isso, o StrictMode estava lá no main.jsx. Coloquei o AbortController e agora aparece uma requisição cancelada, do jeitinho que você falou. Muito obrigada pela paciência, de novo 💛
1 net votes
Thiago Valadares@thiago_pj#2 in Dev Brasil
o caio sendo backend e respondendo pergunta de React melhor que muito front kkkk. lari, quando terminar esse projeto me manda que eu dou mais uma olhada no portfólio
2 net votes
Larissa Souza@lari_codando#3 in Dev Brasil
Combinado, Thiago! Dessa vez vou caprichar no README, prometo 😄
0 net votes
Bruna Schmitt@bruna_dados#6 in Dev Brasil
Bah, passei uma tarde inteira com isso ano passado achando que era bug meu. E tu fez a pergunta muito bem, Lari, com tudo que já tinha testado. Isso é raro!
1 net votes
Pedro Henrique Lima@phzin_71 rep in Dev Brasil
mano eu achava q era bug do vite kkkkkk valeu caio tb aprendi
1 net votes