Criar um hook personalizado de React com TypeScript e testes
Desenhe e implemente um custom hook de React tipado, com limpeza de efeitos, controlo de race conditions, um componente de exemplo e testes prontos a correr. Pensado para ChatGPT, Claude, Gemini e Microsoft Copilot. Inclui 4 variáveis personalizáveis e pode copiá-lo gratuitamente com um clique.
Intermédio · Código · Pendente de revisão editorial
Prompt
Atua como engenheiro sénior de React especializado em hooks reutilizáveis e bem tipados.
Contexto:
- O que o hook deve fazer: {{objetivo_hook}}
- Fonte de dados ou contrato da API: {{contrato_dados}}
- Stack: {{stack}}
- Ferramenta de testes: {{testes}}
Antes de escreveres código, pergunta-me o que faltar de essencial (forma exata da resposta, formato dos erros, se o hook também corre no servidor).
Entregáveis:
1. A API pública do hook: nome (a começar por «use»), parâmetros, valor de retorno e porquê essa forma (objeto ou tuplo).
2. A implementação completa em TypeScript, com tipos explícitos e sem `any`.
3. Tratamento correto de: limpeza ao desmontar, race conditions entre pedidos (AbortController ou flag de descarte), callbacks estáveis (useCallback/useRef só onde importa mesmo) e estados de carregamento, erro e vazio.
4. Um componente de exemplo curto que use o hook.
5. Testes com {{testes}} que cubram o caso feliz, um erro, uma resposta antiga que chega tarde e a desmontagem durante um pedido (com temporizadores falsos se houver debounce). Se escolhi «sem testes», enumera os casos a verificar à mão.
6. Limitações: o que o hook não faz (cache, novas tentativas, SSR) e quando compensaria uma biblioteca como TanStack Query.
Restrições:
- Respeita as regras dos hooks e não uses useEffect para derivar estado que pode ser calculado durante o render.
- Não inventes endpoints nem campos fora de {{contrato_dados}}; usa [PREENCHER] onde faltar informação.
- Comentários apenas quando o motivo não for evidente.
Formato: secções com títulos e um bloco de código por ficheiro, com o respetivo nome.Como utilizar
- Descreve numa frase o que o hook deve resolver e cola o contrato real da tua API. 2. Responde às perguntas antes de o código ser gerado. 3. Copia os ficheiros, corre os testes e pede ajustes concretos se algum falhar.
Exemplo de utilização
Objetivo: pesquisar produtos enquanto o utilizador escreve, com debounce de 300 ms · Contrato: GET /api/produtos?q= devolve { items, total } · Stack: React 18 + Vite · Testes: Vitest.
Exemplo de resultado
API pública
useProductSearch(query, delay?) devolve um objeto { items, total, loading, error }: com quatro valores, é mais legível do que um tuplo.
useProductSearch.ts
import { useEffect, useState } from 'react';
export type Produto = { id: string; nome: string }; // [PREENCHER: campos reais]
type Estado = { items: Produto[]; total: number; loading: boolean; error: Error | null };
const inicial: Estado = { items: [], total: 0, loading: false, error: null };
export function useProductSearch(query: string, delay = 300): Estado {
const [estado, setEstado] = useState<Estado>(inicial);
useEffect(() => {
const q = query.trim();
if (!q) return setEstado(inicial);
const controller = new AbortController();
const timer = setTimeout(async () => {
setEstado((s) => ({ ...s, loading: true, error: null }));
try {
const res = await fetch(`/api/produtos?q=${encodeURIComponent(q)}`, { signal: controller.signal });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data: { items: Produto[]; total: number } = await res.json();
setEstado({ ...data, loading: false, error: null });
} catch (err) {
if (!controller.signal.aborted) setEstado((s) => ({ ...s, loading: false, error: err as Error }));
}
}, delay);
return () => { clearTimeout(timer); controller.abort(); };
}, [query, delay]);
return estado;
}
A limpeza do efeito cancela o temporizador e aborta o pedido anterior, pelo que uma resposta antiga nunca substitui a mais recente…
Dados-chave
- Categoria
- Programação e desenvolvimento · React
- Tipo de resultado
- Código
- Nível
- Intermédio
- Pensado para
- ChatGPT, Claude, Gemini e Microsoft Copilot
- Verificado em
- Pendente de verificação editorial
- Variáveis
- O que o hook deve fazer, Contrato de dados ou API, Stack e Testes
- Idioma
- Português
- Preço
- Gratuito, sem registo
- Atualizado
- 07/11/2026
Perguntas frequentes
Quando compensa um custom hook em vez de lógica no componente?
Quando a mesma lógica com estado se repete em vários componentes ou quando isolá-la torna o componente muito mais legível e testável. Para lógica curta usada uma só vez, nem sempre compensa.
Porque é que o prompt insiste nas race conditions?
São o erro mais comum em hooks que carregam dados: uma resposta lenta de uma pesquisa anterior pode substituir a mais recente. Cancelar ou descartar respostas antigas evita-o.
Substitui o TanStack Query ou o SWR?
Não. Para cache, novas tentativas ou invalidação é melhor uma biblioteca testada. O prompt indica-te quando dar esse passo.
Para que serve este prompt?
Desenhe e implemente um custom hook de React tipado, com limpeza de efeitos, controlo de race conditions, um componente de exemplo e testes prontos a correr.
Com que ferramentas de IA funciona?
Foi pensado para ChatGPT, Claude, Gemini e Microsoft Copilot. Ainda não o verificámos nestas ferramentas, pelo que os resultados podem variar entre elas.
Como personalizo o prompt?
Clique em “Personalizar” e preencha as variáveis (O que o hook deve fazer, Contrato de dados ou API, Stack e Testes). O texto atualiza-se instantaneamente e pode depois copiá-lo com um clique. Os valores ficam guardados apenas no seu navegador.
Preciso de experiência para o utilizar?
É de nível intermédio: convém conhecer o tema para fornecer bom contexto e rever o resultado com sentido crítico.
Este prompt é gratuito?
Sim. Todos os prompts do HomeCasa Prompts são gratuitos, sem registo nem subscrição. Pode também utilizá-los em projetos profissionais.
Posso confiar no resultado da IA?
Trate-o como um rascunho de qualidade: verifique sempre os dados, os números e as afirmações importantes antes de publicar ou tomar decisões.