O hook useEffect do React se tornou um recurso popular na biblioteca React desde sua introdução na versão 16.8. Ele permite que os desenvolvedores executem efeitos colaterais, como buscar dados, atualizar o DOM e assinar eventos dentro de componentes funcionais.

No entanto, o hook useEffect pode ser complicado de usar às vezes. Um erro comum que os desenvolvedores encontram é o “React hook useEffect has a missing dependency”.

Neste artigo, discutiremos as causas desse erro e forneceremos várias soluções para corrigi-lo.

O que causa o erro “React hook useEffect has a missing dependency”?

O erro “React hook useEffect has a missing dependency” ocorre quando o hook useEffect tem uma array de dependências incompleta ou ausente.

A array de dependência é o segundo argumento do hook useEffect e é usada para especificar as variáveis das quais o efeito depende. Isso significa que quando qualquer um dos valores das variáveis especificadas na array de dependência é alterado, o efeito é reexecutado.

Em uma situação em que uma variável da qual o efeito depende não estiver incluída na array de dependência, o efeito poderá não ser reexecutado quando o valor for alterado. Isso pode levar a um comportamento inesperado e a erros em seu aplicativo.

Esse erro não é um erro do React, mas um erro do ESLint. O ESLint fornece um plugin específico para o React, que inclui um conjunto de regras criadas para ajudar os desenvolvedores a escrever um código React melhor. Uma dessas regras é a regra "react-hooks/exhaustive-deps", que detecta o erro “React Hook useEffect has a missing dependency”.

Como exemplo, vamos analisar um componente funcional que tem um estado de contagem. Espera-se que esse componente também registre uma mensagem com o valor de count no console sempre que ele for alterado:

import { useState, useEffect } from 'react';

const App = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(`You clicked ${count} times`);
  }, []);

  return (
    <div>
      <h1>Hello World</h1>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default App;

No exemplo acima, você tem um componente funcional que usa os hooks useState e useEffect. O hook useEffect é usado para registrar em registro uma mensagem com o valor da variável de estado count sempre que ela for alterada.

No entanto, observe que a variável count não está listada na segunda array de argumentos (array de dependência) do hook useEffect. Isso acionará o erro “React hook useEffect has a missing dependency”.

Mensagem de erro "React hook useEffect has a missing dependency".
Mensagem de erro “React hook useEffect has a missing dependency”.

3 maneiras de corrigir o erro “React hook useEffect has a missing dependency”

Esse erro pode ser corrigido de diferentes maneiras, dependendo da abordagem que você deseja usar. Aqui estão as várias maneiras.

  • Adicionar todas as dependências ausentes
  • Usar hooks de memoização ao trabalhar com objetos e funções
  • Desativar a regra do ESLint

1. Adicionar a dependência ausente à array de dependências de useEffect

A maneira mais direta de resolver esse erro é incluir todas as dependências usadas no hook useEffect na array de dependências. Então você pode se perguntar: como eu conheço uma dependência?

Para identificar uma dependência ausente, você precisa observar as variáveis ou os valores usados no hook useEffect. Se qualquer uma dessas variáveis ou valores puder mudar com o tempo, eles deverão ser incluídos na array de dependências.

Por exemplo, no trecho de código fornecido anteriormente, a variável count é usada dentro do hook useEffect, mas não está incluída na array de dependência. Isso significa que, se a variável count for alterada, o hook useEffect não será executado novamente e o componente poderá ter dados obsoletos ou outros problemas.

Para corrigir esse erro, podemos adicionar a variável count à array de dependências, da seguinte forma:

import { useState, useEffect } from 'react';

const App = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(`You clicked ${count} times`);
  }, [count]);

  return (
    <div>
      <h1>Hello World</h1>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default App;

Ao adicionar a variável count ao array de dependências, dizemos ao React para reexecutar o hook useEffect sempre que a variável count for alterada.

Isso garante que o componente sempre tenha dados atualizados e evita o erro “React Hook useEffect has a missing dependency”.

Se você tiver mais de uma dependência, adicione-as à array de dependências e separe-as com uma vírgula:

import { useState, useEffect } from 'react';
const App = () => {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');
  const [fullName, setFullName] = useState('');

  useEffect(() => {
    setFullName(`${firstName} ${lastName}`);
  }, [firstName, lastName]);

  const handleFirstNameChange = (event) => {
    setFirstName(event.target.value);
  };

  const handleLastNameChange = (event) => {
    setLastName(event.target.value);
  };

  return (
    <div>
      <label>
        First Name:
        <input type="text" value={firstName} onChange={handleFirstNameChange} />
      </label>
      <label>
        Last Name:
        <input type="text" value={lastName} onChange={handleLastNameChange} />
      </label>
      <p>Full Name: {fullName}</p>
    </div>
  );
};

export default App;

2. Trabalho com objetos e funções

Ao trabalhar com objetos e arrays, não basta adicioná-los à sua array de dependências; você precisará memorizá-los ou movê-los para o hook useEffect ou para fora do componente para evitar novas renderizações desnecessárias.

Isso ocorre porque, no JavaScript, os objetos e as arrays são comparados por referência e apontam para um local diferente na memória todas as vezes – seu valor será alterado em cada renderização, causando um loop infinito de nova renderização.

Aqui está um exemplo que causa o erro:

import { useState, useEffect } from 'react';

const App = () => {
  const [user, setUser] = useState({});

  // 👇️this will change on every render
  let newUser = { name: 'Jane', age: 28 };

  useEffect(() => {
    setUser(newUser);
  }, [newUser]);

  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
};

export default App;

Você pode corrigir esse erro movendo o objeto para o hook useEffect ou movendo para fora do componente:

import { useState, useEffect } from 'react';

const App = () => {
  const [user, setUser] = useState({});

  useEffect(() => {
    let newUser = { name: 'Jane', age: 28 };
    setUser(newUser);
  }, []);

  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
};

export default App;

Uma maneira melhor de resolver esse problema é usar hooks de memoização como useMemo para o objeto e useCallback para as funções. Isso ajudará você a manter o objeto ou a função dentro do componente e na array de dependência.

Observação: Os hooks de memorização são um conjunto de hooks que permitem que você armazene em cache os resultados de cálculos dispendiosos e evite recalculá-los desnecessariamente.

Esta é a aparência do seu código quando você usar o hook useMemo para memoizar seu objeto:

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

const App = () => {
  const [user, setUser] = useState({});

  const newUser = useMemo(() => {
    return { name: 'John', age: 30 };
  }, []);

  useEffect(() => {
    setUser(newUser);
  }, [newUser]);

  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
};

export default App;

Da mesma forma, ao trabalhar com funções, você pode usar o hook useCallback.

3. Desative a regra ESLint

O erro “React hook useEffect has a missing dependency” é um erro de aviso do ESLint, o que significa que você pode desativar a regra para que ela não lance o erro. Essa abordagem não é recomendada em todos os casos, mas pode ser uma solução rápida se você tiver certeza de que a dependência ausente não é um problema.

Você pode fazer isso adicionando o seguinte comentário antes da linha da array de dependência.

// eslint-disable-next-line react-hooks/exhaustive-deps

Aqui está um exemplo:

useEffect(() => {
  console.log(`You clicked ${count} times`);
  
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

É importante observar que a desativação da regra ESLint pode levar a outros problemas no futuro se você não for cuidadoso. Certifique-se de que você entenda completamente as consequências da desativação de uma regra antes de fazer isso e considere soluções alternativas, se possível.

Resumo

O erro “React hook useEffect has a missing dependency” é um problema comum enfrentado pelos desenvolvedores de React ao trabalhar com o hook useEffect.

Ao corrigir o erro, é importante considerar os melhores métodos para o seu caso de uso específico. Em geral, é melhor evitar desativar a regra do ESLint que está causando o erro, pois isso pode levar a outros problemas no futuro. Em vez disso, tente resolver o problema incluindo a dependência ausente na array de dependências ou usando o hook de memoização correto.

Agora é a sua vez: Você já enfrentou esse problema? Como o resolveu? Existe alguma outra abordagem que você utilizou e que não foi mencionada neste artigo? Compartilhe conosco nos comentários!