Como Você Pode Criar Hooks Personalizados em React?

React fornece muitos hooks embutidos que permitem implementar diferentes funcionalidades em seus projetos. Estes incluem useState, useEffect, useContext e outros. Mas às vezes, você precisará adicionar um recurso que nenhum dos hooks embutidos pode ajudar. Felizmente, você pode criar seus próprios hooks personalizados em React. Hooks personalizados não são tão complicados quanto podem parecer. São apenas funções reutilizáveis que permitem compartilhar lógica entre múltiplos componentes. Isso significa que reutilização é outro motivo pelo qual você gostaria de criar seu próprio hook. Com um hook personalizado, você pode extrair a lógica de qualquer componente que os utilize, como busca de dados, gerenciamento de estado, alternância, efeitos colaterais como verificar o status online ou offline dos usuários e assim por diante. Você pode então importar o hook para usar em qualquer componente, assim você pode se concentrar na renderização e apresentação dentro desses componentes. Isso significa menos repetições e menos duplicações, o que significa menos lugares para fazer alterações quando você quiser fazer qualquer atualização. Agora, vamos dar uma olhada em como você pode criar seu próprio hook personalizado. No React, todos os hooks embutidos começam com a palavra use, então seu hook personalizado deve seguir a mesma convenção. O nome do seu hook personalizado também deve comunicar claramente o que ele faz. Então, se o seu hook personalizado…
  • busca dados, você pode chamá-lo de useFetch
  • ativa e desativa algo, você pode chamá-lo de useToggle
  • ou se ele implementa debouncing, useDebounce é um bom nome
Vamos supor que você queira criar um hook personalizado para adicionar debounce à sua app. Debouncing é uma técnica de programação que limita com que frequência uma função é executada. Funciona esperando até que um usuário pare de realizar uma ação por um período especificado antes de executar a função. Por exemplo, em uma caixa de busca, ao invés de fazer uma chamada de API a cada pressionamento de tecla, o debounce espera até que o usuário pare de digitar por, digamos, 500 milissegundos. Para criar um hook customizado de debouncing, você primeiro precisa criar um arquivo useDebounce.jsx ou useDebounce.js. Convencionalmente, arquivos para quaisquer hooks personalizados que você criar são salvos em uma pasta hooks. Você pode usar alguns hooks embutidos dentro do seu próprio hook personalizado. Para debouncing, você precisa dos hooks useState e useEffect, então importe-os no topo do seu arquivo:
import { useState, useEffect } from "react";
Em seguida, crie uma função useDebounce que recebe value e delay como parâmetros. value é o recurso pelo qual você quer esperar e delay é o período de tempo pelo qual você quer esperar. Como você quer esperar por algum período de tempo, as funções setTimeout e clearTimeout seriam úteis:
function useDebounce(value, delay) {
  const [debouncedValue, setDebouncedValue] = useState(value);

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

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

  return debouncedValue;
}

export { useDebounce };
O estado debouncedValue mantém e retorna o valor atrasado, que só é atualizado após o período de timeout especificado. useEffect é onde a mágica realmente acontece. Se você se lembra da lição anterior, qualquer coisa que exista fora do ciclo de renderização do React, como configurar e limpar um timer, é um efeito colateral e você deve usar o hook useEffect para lidar com eles. Dentro do hook useEffect aqui, você usa setTimeout para definir o debouncedValue. Você então retorna uma função de limpeza que usa clearTimeout para limpar o timeout anterior sempre que value ou delay mudam, ou o componente é desmontado. Para usar este hook, preparamos um array footballers para filtrar com uma barra de pesquisa simples:
const footballers = [
  'Lionel Messi', 'Cristiano Ronaldo', 'Neymar Jr',
  'Kylian Mbappe', 'Mohamed Salah', 'Sadio Mane',
  'Kevin De Bruyne', 'Robert Lewandowski', 'Harry Kane',
  'Sergio Ramos', 'Virgil van Dijk', 'Alisson Becker', 
  'Joshua Kimmich', 'Manuel Neuer', 'Karim Benzema', 
  'Thibaut Courtois', 'Eden Hazard', 'Raheem Sterling',
  'Bruno Fernandes', 'Trent Alexander-Arnold', 'Son Heung-min',
  'Pierre-Emerick Aubameyang','Sergio Aguero', 'Luis Suarez', 
  'Luka Modric', 'Casemiro', 'Frenkie de Jong', 'Gerard Pique',
  'Marc-Andre ter Stegen', 'Keylor Navas', 'Angel Di Maria', 
  "N'Golo Kante", 'Kai Havertz', 'Timo Werner', 'Hakim Ziyech', 
  'Christian Pulisic', 'Mason Mount', 'Olivier Giroud', 'Tammy Abraham', 
  'Kepa Arrizabalaga', 'Ben Chilwell', 'Thiago Silva', 'Kurt Zouma', 
  'John Terry', 'Didier Drogba', 'Frank Lampard', 'Ashley Cole', 'Petr Cech',
];

export default footballers;
E aqui está um componente FootballerSearch que usa o hook useDebounce para atrasar a busca por 1 segundo depois que o usuário para de digitar:
import { useState, useEffect } from "react";
import { useDebounce } from "./hooks/useDebounce";
import footballers from "./footballers";

const FootballerSearch = () => {
  const [query, setQuery] = useState("");
  const debouncedQuery = useDebounce(query, 1000); // Start searching 1 second after the user stops typing

  useEffect(() => {
    if (debouncedQuery) {
      const results = footballers.filter((footballer) =>
        footballer.toLowerCase().includes(debouncedQuery.toLowerCase()),
      );
      console.log("Search results:", results);
    } else {
      console.log("Search results: []");
    }
  }, [debouncedQuery]);

  return (
    <>
      <h1 style={{ textAlign: "center" }}>Footballer Search App</h1>
      <div style={{ textAlign: "center" }}>
        <input
          style={{ padding: "0.5rem", width: "30%" }}
          type="text"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          placeholder="Search for a footballer..."
        />
      </div>
    </>
  );
};

export default FootballerSearch;
Como você pode ver, a variável debouncedQuery é o que inicializa o hook useDebounce com o estado da query (o que o usuário digita) e o delay de 1.000 milissegundos ou 1 segundo. A própria busca é realizada dentro do hook useEffect e os resultados da busca são registrados no console.
Este módulo não possui perguntas. Marque como concluído.