首頁  >  文章  >  web前端  >  使用 React Hook Form Zod 建立表單

使用 React Hook Form Zod 建立表單

Patricia Arquette
Patricia Arquette原創
2024-11-09 11:19:02848瀏覽

介紹

當我開始程式設計時,我需要用純 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