Validação de formulários no React com Hook Form e Zod
Validação de formulários no React com React Hook Form e Zod
A melhor forma de fazer validação de formulários no React hoje é combinar React Hook Form, que cuida do estado e do desempenho do formulário, com Zod, que define as regras de validação em um schema tipado. Você escreve as regras uma vez, o TypeScript infere os tipos automaticamente e o formulário só re-renderiza onde precisa.
##Por que usar React Hook Form e Zod juntos
O React Hook Form trabalha com inputs não controlados, o que reduz re-renderizações em comparação com formulários que guardam cada campo em um useState. Já o Zod é uma biblioteca de validação de schemas pensada para TypeScript, que descreve o formato esperado dos dados e devolve mensagens de erro claras.
Os dois se conectam pelo pacote @hookform/resolvers, que traduz o schema do Zod para o formato que o React Hook Form entende. As vantagens principais são:
- Uma única fonte da verdade: o schema define regras e tipos ao mesmo tempo.
- Menos código repetido: sem validações manuais espalhadas pelo componente.
- Melhor desempenho: menos renderizações durante a digitação.
- Reaproveitamento: o mesmo schema pode validar dados no frontend e no backend.
##Como configurar passo a passo
Instale as dependências:
npm install react-hook-form zod @hookform/resolvers
Depois, crie o schema e conecte ao formulário:
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
const contatoSchema = z.object({
nome: z.string().min(2, "Informe seu nome"),
email: z.string().email("E-mail inválido"),
mensagem: z.string().min(10, "Escreva pelo menos 10 caracteres"),
});
type ContatoForm = z.infer<typeof contatoSchema>;
export function FormularioContato() {
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm<ContatoForm>({ resolver: zodResolver(contatoSchema) });
const onSubmit = async (dados: ContatoForm) => {
// enviar para Supabase, API ou Netlify Function
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("nome")} />
{errors.nome && <span>{errors.nome.message}</span>}
<input {...register("email")} />
{errors.email && <span>{errors.email.message}</span>}
<textarea {...register("mensagem")} />
{errors.mensagem && <span>{errors.mensagem.message}</span>}
<button disabled={isSubmitting}>Enviar</button>
</form>
);
}
O tipo ContatoForm é gerado a partir do schema com z.infer, então qualquer mudança nas regras atualiza os tipos sem trabalho extra.
##Boas práticas de validação de formulários
Algumas decisões fazem diferença na experiência do usuário:
- Mensagens em português e específicas: diga o que está errado e como corrigir.
- Modo de validação adequado: use
mode: "onBlur"ou"onTouched"para não mostrar erros antes de o usuário terminar de digitar. - Valores padrão: defina
defaultValuespara evitar campos indefinidos. - Regras entre campos: use
refineousuperRefineno Zod para validar, por exemplo, confirmação de senha. - Acessibilidade: associe cada mensagem de erro ao campo com
aria-describedbyearia-invalid.
###Validando campos brasileiros
Campos como CPF, CNPJ e telefone podem ser validados com regex ou refine no schema. Lembre que a validação no navegador melhora a experiência, mas nunca substitui a validação no servidor.
##Validação no frontend e no backend com Supabase
Validar só no navegador não protege seus dados, porque qualquer pessoa pode contornar o formulário. Reaproveite o mesmo schema do Zod dentro de uma Edge Function do Supabase ou de uma Netlify Function para checar o payload antes de gravar no banco. Combine isso com Row Level Security para ter segurança em camadas.
##Perguntas Frequentes
Qual a melhor biblioteca para validar formulários no React? React Hook Form com Zod é uma das combinações mais usadas hoje, por unir bom desempenho, tipagem com TypeScript e pouca repetição de código.
O React Hook Form funciona sem Zod?
Sim. Ele possui validação nativa por regras no register. O Zod é recomendado quando o formulário é grande, tem regras entre campos ou quando você quer reaproveitar o schema no backend.
Como pegar o tipo TypeScript a partir do schema Zod?
Use z.infer<typeof meuSchema>. O tipo é gerado automaticamente e acompanha qualquer alteração no schema.
Só validar no frontend é suficiente? Não. A validação no navegador melhora a experiência, mas a validação no servidor é obrigatória para garantir a integridade e a segurança dos dados.
##Conclusão
Adotar React Hook Form com Zod deixa seus formulários mais rápidos, tipados e fáceis de manter. Comece por um formulário de contato, extraia o schema para um arquivo compartilhado e leve a mesma validação ao backend. Na Stormcore, criamos sites, sistemas e automações com esse tipo de boa prática desde o primeiro formulário.
Matérias relacionadas
Copywriting com IA: como criar textos que vendem
Como Conseguir Mais Avaliações no Google: Guia Prático
Code Splitting no React: como usar lazy loading no Vite
Automação com n8n e IA: guia para empresas
Conteúdo gerado pelo usuário (UGC): como usar na sua marca
TanStack Query no React: guia para cache de dados
Pronto para tirar sua ideia do papel?
Fale agora com nosso time de desenvolvimento. Sites, apps, automações, o que você precisar.
Chamar no WhatsAppResposta em até 2 horas