React之react-hook-form使用

一、react-hook-form介绍

React Hook Form是一个高性能、灵活、易拓展、易于使用的表单校验库,用于React Web&Native的表单验证。

(1)安装

npm i react-hook-form
or
yarn add react-hook-form

(2)使用

这是官方提供的使用方法:

  1. from标签使用
import React from 'react';
import { useForm } from 'react-hook-form';

function App() {
  const { register, handleSubmit, errors } = useForm(); // initialise the hook
  const onSubmit = (data) => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input name="firstname" ref={register} /> {/* register an input */}
      <input name="lastname" ref={register({ required: true })} />
      {errors.lastname && 'Last name is required.'}
      <input name="age" ref={register({ pattern: /\d+/ })} />
      {errors.age && 'Please enter number for age.'}
      <input type="submit" />
    </form>
  );
}
  1. 通过buttom控制
    下面是我写的一个函数,通过遍历数组进行显示对应的组件
    数组如下:
{
    "version": "2.0",
    "actions": [
        {
            "text": [
                {
                    "markdown": true,
                    "value": "**ceshi**"
                }
            ],
            "type": "section"
        },
        {
            "type": "divider"
        },
        {
            "text": [
                {
                    "markdown": true,
                    "value": "ceshi1"
                }
            ],
            "type": "section"
        },
        {
            "type": "divider"
        },
        {
            "text": [
                {
                    "markdown": false,
                    "value": "单行文本"
                }
            ],
            "type": "section"
        },
        {
            "cate": "text",
            "min": 10,
            "type": "input",
            "required": true,
            "label": "标签",
            "desc_text": "单行文本",
            "max": 100,
            "placeholder": "(若外发原因为其他,请填写)",
            "name": "other_reason"
        },
        {
            "text": [
                {
                    "markdown": false,
                    "value": "多行文本"
                }
            ],
            "type": "section"
        },
        {
            "cate": "textarea",
            "min": 10,
            "type": "input",
            "required": false,
            "label": "标签",
            "desc_text": "多行文本",
            "max": 100,
            "placeholder": "(若外发原因为其他,请填写)",
            "name": "other_reason2"
        },
        {
            "type": "divider"
        },
        {
            "text": [
                {
                    "markdown": false,
                    "value": "单选"
                }
            ],
            "type": "section"
        },
        {
            "name": "wf_reason1",
            "value": [
                "个人或他人共享文件需要留存"
            ],
            "desc_text": "单选",
            "type": "select",
            "options": [
                {
                    "value": "误操作",
                    "label": "误操作"
                },
               
                {
                    "value": "其他",
                    "label": "其他"
                }
            ],
            "cate": "radio"
        },
        {
            "text": [
                {
                    "markdown": false,
                    "value": "下拉"
                }
            ],
            "type": "section"
        },
        {
            "cate": "select",
            "filterable": true,
            "value": [
                "个人或他人共享文件需要留存"
            ],
            "desc_text": "下拉",
            "type": "select",
            "options": [
                {
                    "value": "误操作",
                    "label": "误操作"
                },
                {
                    "value": "其他",
                    "label": "其他"
                }
            ],
            "name": "wf_reason2"
        },
        {
            "text": [
                {
                    "markdown": false,
                    "value": "多选"
                }
            ],
            "type": "section"
        },
        {
            "name": "wf_reason3",
            "value": [
                "个人或他人共享文件需要留存"
            ],
            "desc_text": "多选",
            "type": "select",
            "options": [
                {
                    "value": "误操作",
                    "label": "误操作"
                },
                {
                    "value": "其他",
                    "label": "其他"
                }
            ],
            "cate": "checkbox"
        },
        {
            "text": [
                {
                    "markdown": false,
                    "value": "申请加入群组:919 测试群"
                },
                {
                    "value": "申请渠道:群名片"
                },
                {
                    "value": "申请加入理由:无"
                }
            ],
            "type": "section"
        },
        {
            "type": "submit",
            "children": [
                {
                    "text": "拒绝",
                    "kind": "normal",
                    "name": "ignore",
                    "verify": false
                },
                {
                    "text": "签收",
                    "kind": "primary",
                    "name": "confirm",
                    "verify": true
                }
            ]
        }
    ]
}

通过type来控制显示的类型,有文本【纯文本,markdown】,下拉【下来,夺权,单选】,输入【input,textarea】,子类用cate来进行控制。
下面是我写的函数,分别对组件进行了封装:

const renderFormItem = useCallback(
    (item, index) => {
      switch (item.type) {
        case 'divider':
          return (
            <div key={index}>
              <div
                style={{
                  border: 'solid 2px #999',
                  transform: 'scaleY(0.2)',
                }}
              ></div>
              <WhiteSpace size="md" />
            </div>
          );
        case 'input':
          return (
            <Controller
              key={index}
              name={item.name}
              control={control}
              defaultValue={item.value}
              rules={{
                required: item.required
                  ? '【' + item.name + '】输入项不能为空!'
                  : false,
                maxLength: {
                  value: item.max,
                  message: '输入不能超过' + item.max + '个字符!',
                },
                minLength: {
                  value: item.min,
                  message: '输入不能小于' + item.min + '个字符!',
                },
              }}
              render={({ field }) => {
                return (
                  <InputComponent
                    cate={item.cate}
                    name={item.name}
                    label={item.label}
                    desc_text={item.desc_text}
                    placeholder={item.placeholder}
                    value={field.value}
                    max={item.max}
                    min={item.min}
                    onChange={(e: any) => {
                      return field.onChange(e);
                    }}
                  />
                );
              }}
            />
          );
        case 'select':
          return (
            <Controller
              key={index}
              name={item.name}
              control={control}
              defaultValue={item.cate === 'radio' ? '' : []}
              rules={{
                required: item.required
                  ? '【' + item.name + '】选择项不能为空!'
                  : false,
              }}
              render={({ field }) => {
                return (
                  <SelectComponent
                    name={item.name}
                    cate={item.cate}
                    options={item.options}
                    value={field.value}
                    onChange={(e) => {
                      return field.onChange(e);
                    }}
                  />
                );
              }}
            />
          );
        case 'section':
          return (
            <TextComponent key={index} text={item.text}>
              文本
            </TextComponent>
          );
        case 'submit':
          return (
            <ButtonComponent
              key={index}
              childrens={item.children}
              type={'submit'}
              onClick={(action) => {
                handleSubmit(onSubmit(action))();
              }}
            />
          );
        default:
          return;
      }
    },
    [control, handleSubmit, onSubmit]
  );

onsubmit函数

 const onSubmit = useCallback(
    (action: string) => {
      return (data: any) => {
      //可以拿到对应的数据
       console.log(action, data);
      };
    },
    []
  );

显示错误提示的函数:

  const rederError = (item: any) => {
    const err_str = errors[item.name];
    if (!err_str) {
      return null;
    } else {
      return <span className={styles['error-info']}>{err_str.message}</span>;
    }
  };

页面主函数:

<div className={styles['ueba-div']}>
      {loading && (
        <div className={styles['loading-div']}>
          <img
            src={'img/loading.gif'}
            className={styles['loading-div__img']}
            alt=""
          />
        </div>
      )}
      <WingBlank>
        <div>
          {list.map((item, index) => {
            return (
              <div key={index}>
                {renderUeba(item, index)}
                {rederError(item)}
              </div>
            );
          })}
        </div>
      </WingBlank>
    </div>

参考文章:
https://react-hook-form.com/api/usecontroller/controller/
上述只是个用法代码,下次准备写一版封装好的form组件

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值