Sobes.tech
Middle

Quais são as regras para escrever hooks no React?

sobes.tech IA

Resposta da IA

  • Chamar os hooks apenas ao nível superior dos componentes funcionais ou dentro de outros hooks personalizados. Não se deve chamar hooks em ciclos, condições ou funções aninhadas.
  • Chamar hooks apenas dentro de componentes funcionais React. Não se deve chamá-los em funções JavaScript normais ou em componentes de classe.
  • O uso de useCallback para memorizar funções e useMemo para memorizar cálculos ajuda a otimizar o desempenho.
  • Usar useEffect para efeitos colaterais (carregamento de dados, assinaturas, etc.), especificando um array de dependências para controlar a execução do efeito.
  • Manter a ordem de chamada dos hooks em cada renderização do componente. React confia nesta ordem para ligar corretamente o estado e os efeitos.
  • Usar dependências estáveis nos arrays de dependências de useEffect, useCallback, useMemo. Não passar objetos ou funções criados em cada renderização sem necessidade.
  • Criar hooks personalizados para reutilizar a lógica de estado entre componentes. Os nomes dos hooks personalizados devem começar com use.
// Exemplo correto: chamar hooks no nível superior
function MyComponent() {
  const [count, setCount] = useState(0); // No nível superior

  useEffect(() => { // No nível superior
    document.title = `Você clicou ${count} vezes`;
  }, [count]); // Array de dependências

  const handleClick = useCallback(() => { // No nível superior
    setCount(c => c + 1);
  }, []); // Função memoizada

  return (
    <div>
      <p>Você clicou {count} vezes</p>
      <button onClick={handleClick}>
        Clique aqui
      </button>
    </div>
  );
}

// Exemplo incorreto: chamar hook em condição
// function MyComponentWithBadHook() {
//   if (someCondition) {
//     const [count, setCount] = useState(0); // INCORRETO: chamada em condição
//   }
//   // ...
// }

// Exemplo incorreto: chamar hook em ciclo
// function MyComponentWithAnotherBadHook() {
//   for (let i = 0; i < 5; i++) {
//     const [value, setValue] = useState(i); // INCORRETO: chamada em ciclo
//   }
//   // ...
// }