首页 >web前端 >js教程 >使用 React Hook Form Zod 构建表单

使用 React Hook Form Zod 构建表单

Patricia Arquette
Patricia Arquette原创
2024-11-09 11:19:02885浏览

介绍

当我开始编程时,我需要用纯 JavaScript 编写大量代码来从表单收集数据。从那时起,Web 开发已经发展得如此之快,以至于今天我们有了抽象了大部分工作的库,使得管理表单数据变得更加容易。

在本文中,我将向您展示如何使用 React Hook Form 来处理表单数据,并使用 zod 以高效且有组织的方式验证这些数据。

我很着急,给我完整的代码

它在你手里:

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'],
  });

此架构定义了每个字段所需的类型和验证。使用 .refine() 方法来确保“密码”和“确认”字段中输入的密码相同。

.refine((data) => data.password === data.confirm, {
  message: 'Senhas não conferem!',
  path: ['confirm'],
});

与 React Hook Form 和 Zod Resolver 集成

React Hook Form 是一个表单库,它通过减少不必要的重新渲染和简化数据操作来提高性能。我使用 useForm() 来配置表单,通过 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),
  });

我在 useForm() 中使用的函数和变量是:

  • handleSubmit:处理表单提交。
  • register:将表单字段绑定到React Hook Form数据管理。
  • 重置:重置表单。
  • isSubmitting:表示表单是否正在提交。
  • 错误:存储每个字段的验证错误。 ### 表单提交功能 为了模拟表单提交,我创建了handleSignup函数,它添加了一个等待时间来查看isSubmitting状态并显示一条带有toast的成功消息:
async function handleSignup(data: SignUpForm) {
  console.log(data);
  await new Promise((resolve) => {
    setTimeout(resolve, 2000);
  });
  reset();
  toast.success('Conta criada com sucesso!');
}

然后我将函数添加到表单中:

<form onSubmit={handleSubmit(handleSignup)} className="space-y-4 w-full">

最后,我使用寄存器来命名哪个字段属于哪个属性,并显示错误(如果存在):

<div classname="space-y-2">;
  名称标签>
  



<p>结果如下所示:</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>
  
  
  最后的考虑因素
</h2>

<p>在本文中,我展示了一种集成 React Hook Form 和 zod 来验证不受控制的表单的简单方法。该库还可以与受控组件配合使用,因此请查阅文档以探索更多选项。</p>


          </div>

            
        

以上是使用 React Hook Form Zod 构建表单的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn