DEV Community

Cover image for Validação de Formulários com React-Hook-Form e Zod
Vitor Rios
Vitor Rios

Posted on • Edited on

4 1 1 1

Validação de Formulários com React-Hook-Form e Zod

Introdução

Gerenciar formulários em aplicações React pode ser desafiador, especialmente quando se trata de validação e gerenciamento de estados. A combinação de React-Hook-Form, TypeScript e Zod oferece uma solução elegante e eficiente para esses desafios. Este artigo explora os benefícios dessa integração, demonstrando como ela simplifica o gerenciamento de formulários, comparando com a abordagem tradicional usando useState.

Gerenciamento Tradicional de Formulários com useState

Primeiro, vejamos um exemplo de gerenciamento de formulário com useState:

import React, { useState } from 'react';

const TraditionalForm = () => {
    const [name, setName] = useState('');
    const [email, setEmail] = useState('');
    const [errors, setErrors] = useState({ name: '', email: '' });

    const validate = () => {
        let isValid = true;
        const errors = { name: '', email: '' };

        if (!name) {
            errors.name = 'O nome é obrigatório.';
            isValid = false;
        } else if (name.length < 3) {
            errors.name = 'O nome deve ter mais de 3 caracteres.';
            isValid = false;
        }

        if (!email) {
            errors.email = 'O email é obrigatório.';
            isValid = false;
        } else if (!/\S+@\S+\.\S+/.test(email)) {
            errors.email = 'Email inválido.';
            isValid = false;
        }

        setErrors(errors);
        return isValid;
    };

    const handleSubmit = (event) => {
        event.preventDefault();
        if (validate()) {
            // Lógica de submissão do formulário
            console.log('Formulário submetido:', { name, email });
        }
    };

    return (
        <form onSubmit={handleSubmit}>
            <div>
                <input
                    value={name}
                    onChange={(e) => setName(e.target.value)}
                    placeholder="Nome"
                />
                {errors.name && <p style={{ color: 'red' }}>{errors.name}</p>}
            </div>

            <div>
                <input
                    value={email}
                    onChange={(e) => setEmail(e.target.value)}
                    placeholder="Email"
                />
                {errors.email && <p style={{ color: 'red' }}>{errors.email}</p>}
            </div>

            {/* Outros campos e botão de submit */}
            <button type="submit">Enviar</button>
        </form>
    );
};

export default TraditionalForm;
Enter fullscreen mode Exit fullscreen mode

Esta abordagem requer a manutenção de estados separados para cada campo e lógica manual de validação, o que pode tornar o componente extenso e difícil de manter, especialmente em formulários complexos.

Antes de mergulharmos nos exemplos, é necessário configurar nosso ambiente com as bibliotecas necessárias. Aqui estão os passos para configurar React-Hook-Form e o Zod em seu projeto React.

Instalando as Dependências

Execute o seguinte comando para instalar React-Hook-Form e Zod:

npm install react-hook-form zod @hookform/resolvers
Enter fullscreen mode Exit fullscreen mode

Agora, vamos introduzir React-Hook-Form e Zod, utilizando TypeScript para uma integração tipo-segura.

Configurando o Formulário com React-Hook-Form e Zod

import React from 'react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';

const schema = z.object({
    name: z.string().min(3, 'Nome é obrigatório'),
    email: z.string().email('Email inválido')
});

type FormData = z.infer<typeof schema>;

const ModernForm = () => {
    const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
        resolver: zodResolver(schema)
    });

    const onSubmit = (data: FormData) => {
        console.log(data);
    };

    return (
        <form onSubmit={handleSubmit(onSubmit)}>
            <input {...register('name')} />
            {errors.name && <p>{errors.name.message}</p>}

            <input {...register('email')} />
            {errors.email && <p>{errors.email.message}</p>}

            {/* Outros campos e botão de submit */}
        </form>
    );
};
Enter fullscreen mode Exit fullscreen mode

Benefícios da Abordagem Moderna

  • Menos Boilerplate: React-Hook-Form reduz significativamente o código necessário para gerenciar estados e eventos de formulário.
  • Validação Integrada: Zod oferece uma forma declarativa e poderosa de definir esquemas de validação, simplificando a lógica de validação.
  • Mensagens de Erro Gerenciadas: As mensagens de erro são gerenciadas de forma centralizada e automatizada.
  • Tipagem Forte com TypeScript: A integração com TypeScript assegura que os dados do formulário estejam sempre alinhados com o esquema definido, melhorando a segurança e a previsibilidade do código.

Comparação e Conclusão

Comparando as duas abordagens, é evidente que React-Hook-Form, combinado com Zod e TypeScript, oferece uma solução mais limpa, organizada e eficiente para o gerenciamento de formulários em React. O código torna-se mais legível e fácil de manter, enquanto a validação e o gerenciamento de erros são simplificados e mais robustos. Esta stack é particularmente útil em formulários grandes e complexos, onde a abordagem tradicional pode se tornar rapidamente insustentável. Em suma, a adoção de React-Hook-Form, TypeScript e Zod em projetos React não só melhora a qualidade do código, mas também acelera o processo de desenvolvimento, permitindo que os desenvolvedores se concentrem mais na lógica de negócios e menos na mecânica do gerenciamento de formulários.

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay