DEV Community

judsonkerller
judsonkerller

Posted on

Criação de Hooks Personalizados no React: Reutilização de Lógica de Forma Inteligente

Se você já trabalhou em projetos React, provavelmente percebeu que algumas lógicas são repetidas em diferentes componentes. Isso pode tornar o código menos manutenível e mais propenso a erros.
Imagine que você precise implementar um comportamento de debounce em múltiplos componentes para otimizar chamadas a uma API. Em vez de copiar e colar o mesmo código, você pode criar um custom hook (hook personalizado), centralizando a lógica e reaproveitando-a de forma elegante.

No nosso papo de hoje, vamos explorar o conceito de custom hooks, como criá-los, boas práticas, como vivem, o que comem (essas duas últimas foram zueira pessoal rsrs), e um exemplo real de um hook de debounce. Então pegue seu cafézin e rumbora aprender mais sobre hooks.

O que são Hooks Personalizados?

São funções JavaScript que utilizam os hooks padrões do React para encapsular e reutilizar lógica compartilhada entre componentes. Eles seguem a convenção de nome começando com "use" ("useDebounce").
Eles permitem separar preocupações, melhorar a legibilidade e reduzir redundância no seu código.

Criando um Hook Personalizado: useDebounce

Vamos criar um hook que atrasa a execução de uma função até que o usuário pare de digitar por um tempo determinado.

import { useState, useEffect } from 'react';

function useDebounce<T>(value: T, delay: number): T {
  const [debounceValue, setDebounceValue] = useState(value);

  useEffect(() => {
    const handler = setTimeout(() => {
     setDebounceValue(value);
    }, delay)

    return () => {
      clearTimeout(handler);
    };
  }, [value, delay]);

  return debounceValue;
}

export { useDebounce };
Enter fullscreen mode Exit fullscreen mode

Agora, podemos usar o hook personalizado que acabamos de criar, dentro de um componente para otimizar chamadas a uma API de pesquisas, sem que seja feito uma chamada a cada vez que o usuário digitar algo no input, por exemplo.

import { useState } from "react";
import useDebounce from "./useDebounce";

function SearchInput() {
  const [searchTerm, setSearchTerm] = useState("");
  const debouncedSearchTerm = useDebounce(searchTerm, 500);

  useEffect(() => {
    if (debouncedSearchTerm) {
      console.log("Buscando por:", debouncedSearchTerm);
      // Aqui você pode chamar uma API, por exemplo
    }
  }, [debouncedSearchTerm]);

  return (
    <input
      type="text"
      placeholder="Digite sua pesquisa..."
      value={searchTerm}
      onChange={(e) => setSearchTerm(e.target.value)}
    />
  );
}
Enter fullscreen mode Exit fullscreen mode

Boas práticas ao criar Hooks Personalizados

  1. Nomeie corretamente: Comece sempre com o use para garantir que o React reconheça como um hook.
  2. Evite dependências desnecessárias: Utilize apenas os estados e useEffect's se realmente forem necessários para evitar re-renderizações inesperadas.
  3. Mantenha genérico e reutilizável: Evite hardcodes dentro do hook. Prefira passar valores via props.
  4. Escreva testes para seus hooks: Utilize Jest e React Testing Library para validar o comportamento esperado.

Extra: Adote a prática de por testes em todo código que você fizer, pois assim você garante o funcionamento para o qual o mesmo foi criado.

Pra finalizarmos, os hooks personalizados são uma forma poderosa de organizar e reutilizar lógica dentro do React. No exemplo que vimos hoje, transformamos uma lógica repetitiva em um hook que podemos utilizar em diversos componentes que aguardam esse comportamento, e ficou bem estruturado, falaê!? rsrs

Se você quiser se aprofundar, tente criar outros hooks personalizados, observe no seu dia a dia alguma lógica que se repete no projeto que você esteja atualmente e tente implementar - se possível, claro, dependendo do time e contexto que você esteja inserido - garanto que isso só vai trazer benefícios para você e principalmente pro seu time.

Curtiu o artigo? Curtiu o papo? Que outro hook personalizado você gostaria de ver? Deixe seu comentário!🚀

Top comments (0)