V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
jsun969
V2EX  ›  前端开发

如何在 Ant Design 中使用 React Hook Form?

  •  
  •   jsun969 ·
    jsun969 · 2023-04-16 13:53:45 +08:00 · 1569 次点击
    这是一个创建于 621 天前的主题,其中的信息可能已经有所发展或是发生改变。

    博客原文:https://jsun.lol/blog/how-to-use-react-hook-form-in-ant-design-cn
    掘金:https://juejin.cn/post/7222484074480713783

    前言

    先解释一下标题。我想 Ant Design 这个组件库一定是被每个 React 程序员所熟知的。作为一款由阿里背书的前端组件库,其在做后台管理等业务,尤其方便。

    但是 React Hook Form 这个库,可能在国内并没有那么火。尽管 Ant Design 拥有自己的 Form 组件,但是 React Hook Form 是一个非常优秀的表单处理库

    其优点在于:

    1. 强性能,减少渲染次数
    2. 轻量无依赖
    3. 类型安全
    4. 支持多种验证库校验(如 Zod 、Yup 、Class Validator 、Ajv 等等)
    5. 支持多种 UI 库

    GitHub ( 3w+⭐):https://github.com/react-hook-form/react-hook-form
    官网:https://react-hook-form.com

    从功能上来说,其比 Ant Design 的 Form.useForm 要强大不少。但是 Ant Design 目前并没有官方支持 React Hook Form 。

    解决

    为了解决在 Ant Design 中使用 React Hook Form 。我为此写了一个开源库来包装 Ant Design 的 Form.Item

    GitHub: https://github.com/jsun969/react-hook-form-antd

    示例

    CodeSandbox 示例

    其中使用了 Zod 进行表单校验

    使用

    原表单

    首先,你可能原来有这样一个表单

    <Form onFinish={onFinish}>
      <Form.Item
        label="Username"
        name="username"
        rules={[
          { required: true, message: 'Required' },
          { max: 15, message: 'Username should be less than 15 characters' },
        ]}
      >
        <Input />
      </Form.Item>
      <Form.Item
        label="Password"
        name="password"
        rules={[{ required: true, message: 'Required' }]}
      >
        <Input.Password />
      </Form.Item>
      <Form.Item name="remember" valuePropName="checked">
        <Checkbox>Remember me</Checkbox>
      </Form.Item>
      <Form.Item>
        <Button type="primary" htmlType="submit">
          Submit
        </Button>
      </Form.Item>
    </Form>
    

    使用 React Hook Form

    使用 React Hook Form 的 useForm 并获取 control

    const { control } = useForm({
      defaultValues: { username: 'jsun969', password: '', remember: true },
    });
    

    替换 Form.Item

    react-hook-form-antd 中使用 FormItem 代替 Form.Item,将 control 传递给每个 FormItem

    这样一来,每个 FormItem 都受到 React Hook Form 的控制,并且 name (即表单字段名)可以从 control 中推断

    import { FormItem } from 'react-hook-form-antd';
    
    // ...
    <Form onFinish={onFinish}>
      <FormItem control={control} label="Username" name="username">
        <Input />
      </FormItem>
      <FormItem control={control} label="Password" name="password">
        <Input.Password />
      </FormItem>
      <FormItem control={control} name="remember" valuePropName="checked">
        <Checkbox>Remember me</Checkbox>
      </FormItem>
      <Form.Item>
        <Button type="primary" htmlType="submit">
          Submit
        </Button>
      </Form.Item>
    </Form>;
    

    用表单验证库(本文中使用 Zod ,其他验证库使用方法见 React Hook Form Resolver) 代替原先的 rules

    import { zodResolver } from '@hookform/resolvers/zod';
    import * as z from 'zod';
    
    // ...
    
    const schema = z.object({
      username: z
        .string()
        .min(1, { message: 'Required' })
        .max(15, { message: 'Username should be less than 15 characters' }),
      password: z.string().min(1, { message: 'Required' }),
      remember: z.boolean(),
    });
    
    const App = () => {
      const { control } = useForm({
        defaultValues: { username: 'jsun969', password: '', remember: true },
        resolver: zodResolver(schema),
      });
      // ...
    };
    

    onFinish 中使用 React Hook Form 的 handleSubmit

    const { control, handleSubmit } = useForm(...);
    
    return (
        <Form
          style={{ maxWidth: 600 }}
          onFinish={handleSubmit((data) => {
            ...
          })}
        >
        // ...
        </Form>
    );
    

    搞定

    如此一来,即可在 Ant Design 中很方便地使用 React Hook Form 。
    以上使用教程的结果即为 CodeSandbox 示例

    3 条回复    2023-05-21 14:27:43 +08:00
    xubeiyan
        1
    xubeiyan  
       2023-04-16 22:42:24 +08:00 via Android
    圣诞节那个事件之后拒绝用 antd ,material UI 我觉得可以
    jsun969
        2
    jsun969  
    OP
       2023-04-17 18:49:24 +08:00
    @xubeiyan 国内使用 antd 的公司还是相当多的。MUI 也有 React Hook Form 的库: https://github.com/dohomi/react-hook-form-mui
    kkxi22
        3
    kkxi22  
       2023-05-21 14:27:43 +08:00
    react hook form 严格来说和 antd 没关系,可以和任何组件库或者自己的写的组件结合。只需要对每个表单组件封装一个 hook form 的胶水层就可以了,可以用 hook 的方式处理表单联动是他最大的优势。采用 yup 的 schame 校验方式,让表单校验变得异常优雅。确实是一个很好用工具
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3204 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 10:49 · PVG 18:49 · LAX 02:49 · JFK 05:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.