Quand j'ai commencé à programmer, j'avais besoin d'écrire beaucoup de code en JavaScript pur pour collecter les données d'un formulaire. Depuis lors, le développement Web a tellement évolué que nous disposons aujourd'hui de bibliothèques qui résument une grande partie de ce travail, facilitant ainsi la gestion des données de formulaire.
Dans cet article, je vais vous montrer comment utiliser React Hook Form pour travailler avec les données de formulaire et zod pour valider ces données de manière efficace et organisée.
C'est entre vos mains :
import { Label } from '@/components/ui/label'; import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; import { Gamepad, Gamepad2 } from 'lucide-react'; import { useForm } from 'react-hook-form'; import { z } from 'zod'; import { zodResolver } from '@hookform/resolvers/zod'; import { toast, Toaster } from 'sonner'; const signUpForm = z .object({ name: z .string() .min(2, { message: 'Nome deve ter ao menos 2 caracteres' }) .max(50, { message: 'Nome deve ter no máximo 50 caracteres' }), email: z.string().email().max(100, { message: 'E-mail deve ter no máximo 100 caracteres' }), password: z.string().max(100, { message: 'Senha deve ter no máximo 100 caracteres' }), confirm: z.string(), }) .refine((data) => data.password === data.confirm, { message: 'Senhas não conferem!', path: ['confirm'], }); type SignUpForm = z.infer<typeof signUpForm>; export function App() { const { handleSubmit, register, reset, formState: { isSubmitting, errors }, } = useForm<SignUpForm>({ resolver: zodResolver(signUpForm), }); async function handleSignup(data: SignUpForm) { console.log(data); await new Promise((resolve) => { setTimeout(resolve, 2000); }); reset(); toast.success('Conta criada com sucesso!'); } return ( <> <Toaster richColors /> <div className="min-h-screen lg:grid lg:grid-cols-2 antialiased gap-8"> <div className="hidden lg:flex h-full justify-center border-r border-foreground/5 bg-foreground text-muted-foreground items-center gap-3 text-lg"> <Gamepad2 /> <span className="font-semibold">gamers.shop</span> </div> <div className="flex flex-col items-center justify-center gap-6 min-h-screen"> <div className="px-10 w-96 h-full flex flex-col justify-center items-center lg:w-[500px]"> <h1 className="flex items-center gap-2 mb-4 text-2xl font-semibold tracking-tight"> <Gamepad /> Crie sua conta <Gamepad /> </h1> <form onSubmit={handleSubmit(handleSignup)} className="space-y-4 w-full "> <div className="space-y-2"> <Label htmlFor="name">Nome</Label> <Input> <h2> Tutorial </h2> <h3> Estruturando o Formulário </h3> <p>Primeiro, criei um formulário com quatro campos: nome, e-mail, senha e confirmação de senha. Para facilitar o desenvolvimento da interface, utilizei shadcn, tailwind e lucide-react. O uso de classes CSS pode parecer um pouco detalhado, mas elas ajudam a manter um design consistente.<br> </p> <pre class="brush:php;toolbar:false"><form className="space-y-4 w-full "> <div className="space-y-2"> <Label htmlFor="name">Nome</Label> <Input> <p>Criei 4 campos nesse form: nome, e-mail, password e confirm. Preciso validá-los de alguma forma. Como esse exemplo server para explicar o uso de zod, evitei utilizar as propriedades nativas do HTML (required, maxlength etc).</p> <h3> Validação de Dados com Zod </h3> <p>Para garantir que os dados inseridos nos campos estão corretos, criei um schema de validação com o zod. O schema define as restrições para cada campo e personaliza as mensagens de erro:<br> </p> <pre class="brush:php;toolbar:false">import { z } from 'zod'; const signUpFormSchema = z .object({ name: z .string() .min(2, { message: 'Nome deve ter ao menos 2 caracteres' }) .max(50, { message: 'Nome deve ter no máximo 50 caracteres' }), email: z.string().email().max(100, { message: 'E-mail deve ter no máximo 100 caracteres' }), password: z.string().max(100, { message: 'Senha deve ter no máximo 100 caracteres' }), confirm: z.string(), }) .refine((data) => data.password === data.confirm, { message: 'Senhas não conferem!', path: ['confirm'], });
Ce schéma définit les types et validations requis pour chaque champ. La méthode .refine() a été utilisée pour garantir que les mots de passe saisis dans les champs « mot de passe » et « confirmer » sont les mêmes.
.refine((data) => data.password === data.confirm, { message: 'Senhas não conferem!', path: ['confirm'], });
React Hook Form est une bibliothèque de formulaires qui améliore les performances en réduisant les rendus inutiles et en simplifiant la manipulation des données. J'ai utilisé useForm() pour configurer le formulaire, en passant le schéma de validation via zodResolver :
import { zodResolver } from '@hookform/resolvers/zod'; import { useForm } from 'react-hook-form'; type SignUpForm = z.infer<typeof signUpFormSchema>; const { handleSubmit, register, reset, formState: { isSubmitting, errors }, } = useForm<SignUpForm>({ resolver: zodResolver(signUpFormSchema), });
Les fonctions et variables que j'ai utilisées depuis useForm() sont :
async function handleSignup(data: SignUpForm) { console.log(data); await new Promise((resolve) => { setTimeout(resolve, 2000); }); reset(); toast.success('Conta criada com sucesso!'); }
Puis j'ai ajouté la fonction au formulaire :
<form onSubmit={handleSubmit(handleSignup)} className="space-y-4 w-full">
Et enfin, j'ai utilisé register pour nommer quel champ appartient à quelle propriété, et j'ai montré les erreurs (si elles existent) :
<div className="space-y-2"> <Label htmlFor="nom">Nom</Label> <entr> <p>Le résultat ressemblait à ceci :</p> <p><img src="https://img.php.cn/upload/article/000/000/000/173112234459208.jpg" alt="Formulários com React Hook Form Zod"></p> <h2> Considérations finales </h2> <p>Dans ce texte, j'ai montré un moyen simple d'intégrer React Hook Form et zod pour valider des formulaires non contrôlés. La bibliothèque fonctionne également avec des composants contrôlés, alors consultez la documentation pour explorer plus d'options.</p> </entr>
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!