在React中使用react-hook-form和zod实现表单
首先
使用图书馆
React-hook-form:這是一個非常方便的工具,可以輕鬆控制表單的值和驗證。
zod:據說,這是一個方便的型別定義工具。
经验使用
React-hook-form: 我没有主要使用过它,但在工作中有接触过。
zod: 虽然我没有接触过,但听说它很方便,所以我想借此机会学习一下。
设计
让我们在下面创建的项目中,使用React-hook-form为登录添加验证功能。
import { Box, Button, Paper, TextField, Typography } from '@mui/material';
export const  Login = () => {
  return (
    <>
      <Paper
        elevation={3}
        sx={{
          borderRadius: 6,
          p: 4,
          height: '70vh',
          width: '280px',
          m: '20px auto',
        }}
      >
        <Box
          mt={8}
          display='flex'
          flexDirection='column'
          gap={5}
          alignItems='center'
        >
          <Typography variant='h5' fontWeight="bold">ログイン画面</Typography>
          <TextField
            type='id'
            name='user_id'
            variant='standard'
            placeholder='ユーザーIDを入力してください'
            fullWidth
          />
          <TextField
            type='password'
            name='password'
            variant='standard'
            placeholder='パスワードを入力してください'
            fullWidth
          />
          <Button type='submit' color='primary' variant='contained' fullWidth>
            ログイン
          </Button>
        </Box>
      </Paper>
    </>
  );
}

点击上面的登录按钮后,让我们根据验证结果来进行实施,能够通过验证或成功。
在普通的登录页面上,我们没有进行这样的验证,但作为预期情况,
ID:电子邮件地址的格式
PW:至少8个字符,最多32个字符,包括半角英文字母和数字。
我会以这种方式设想。
那么就来实施吧~
实施
响应式钩子表单
使用 npm i react-hook-form 安装 react-hook-form。
import { Box, Button, Paper, TextField, Typography } from '@mui/material';
// import する
import { useForm } from "react-hook-form";
export const Login = () => {
  
  const { register, handleSubmit, watch, formState: { errors } } = useForm();
  return (
                    --- 省略 ---
  );
}
const { 注册, 提交, 监听, 表单状态: { 错误 } } = useForm();
使用 useForm 来实现上述功能。
以下是简要解释。如果您在实施时需要回顾,请随时参考这里,无需完全了解。
register : 各 input 要素に どのような名前が対応するか設定するためのもの、Validationもこの中でかけれる。
handleSubmit: form にわたして、登録ボタン押下時に行う処理を記述
watch : リアルタイムで今入っている値を管理する。
errors : validation に引っかかった場合のエラーを管理する。
设置注册时的处理程序
将注册时的处理作为一个函数。
  /**
   * 登録時の処理を関数化
   * @param  data formから受け取る値
   */
  const onSubmit = (data) => {
    // アラートで結果出してみる (見やすいようにJSON 形式にする)
    alert(JSON.stringify(data));
  };
在 form 标签中传递注册时的处理程序。
 <form onSubmit={handleSubmit(onSubmit)}>
设定对每个要素的命名
使用register方法将适当的命名设置到每个TextField中。
            <TextField
              type='id'
              name='id'
              {...register('id')}
              variant='standard'
              placeholder='ユーザーIDを入力してください'
              fullWidth
            />
            <TextField
              type='password'
              name='password'
              {...register('password')}
              variant='standard'
              placeholder='パスワードを入力してください'
              fullWidth
            />
在这个阶段,虽然还没有进行验证的设置,但是当点击登录按钮时,我们可以确认值已经被接收到了。

验证的实现
    <TextField
              type='id'
              name='id'
              {...register('id', { required: true })}
              error={errors.id}
              helperText={errors.id?.message}
              variant='standard'
              placeholder='ユーザーIDを入力してください'
              fullWidth
            />
            <TextField
              type='password'
              name='password'
              {...register('password', { required: true })}
              error={errors.password}
              helperText={errors.password?.message}
              variant='standard'
              placeholder='パスワードを入力してください'
              fullWidth
            />
首先,設定如下,如果值不存在,只將表單設為紅色。
(雖然助手文本(helperText)未正常顯示,暫時忽略)
举动的感觉就是这样

佐德
因为我们想要对项目进行简单的验证,所以我们要使用zod进行详细的验证。
让我们通过npm安装zod,进行zod的安装。
import { z } from "zod";
/**
   * zod での Validation
   */
  const FormData = z.object({
    id: z.string().email("メアドじゃない"),
    password: z
      .string()
      .min(8, "8文字以下だ")
      .max(32, "32文字以上だ")
      .regex(/^(?=.*?[a-z])(?=.*?\d)[a-z\d]{8,100}$/i, "PWに半角英数字入れて"),
  });
在提交时添加验证。
import { z, ZodError } from "zod";
  /**
   * 登録時の処理を関数化
   * @param  data formから受け取る値
   */
  const onSubmit = (data) => {
    try {
      FormData.parse(data);
      // アラートで結果出してみる (見やすいようにJSON 形式にする)
      alert(JSON.stringify(data));
    } catch (e) {
      if (e instanceof ZodError) {
        alert(JSON.stringify(e.flatten().fieldErrors));
      } else {
        console.log(e);
      }
    }
  };
确认行动
失败

失败
- 
- ID: aaaaa@gmail.com
 
 
PW: aaaaaa

取决于你如何定义它,它可能意味着实现目标、克服困难、获得荣誉,或者带来内心的满足。
- 
- ID: aaaaa@gmail.com
 
 
PW: aaaaa12345

附言
这次虽然没有将项目转为TypeScript,但我还是强行尝试了一下用zod作为验证方式。
说实话,在这个案例中,react-hook-form内置的验证功能已经足够了。
不过,zod本身非常直观和易懂。
我觉得 Zod 在 TypeScript 项目中发挥作用时,主要是用于处理复杂的架构类型之间的交互。通过使用 Zod,可以进行类型安全的开发,这也是最近的流行趋势,更重要的是易于理解。
再见(じゃあまた)(˙︶˙)ノ,我们下次再见吧(マタネー)。