粘贴值后反应钩子表单验证不起作用

EM_*_*M_A 7 reactjs react-hooks react-hook-form

我为表单创建了一个模型,该模型通过它进行映射以使用react-hook-form创建表单

当我第一次提交表格时,一切都很好。但在其他时候,当我将值粘贴到输入中时,验证无法正常工作(它显示所需的错误,但输入不为空)

这是模型:

export const formData = [
  {
    id: 1,
    type: "text",
    labelRequired: true,
    label: "name",
    shape: "inline",
    placeholder: "name",
    name: "nameOne",
    validation: {
      required: true,
      minLength: 8,
    },
    size: 6,
  },
  {
    id: 2,
    type: "text",
    labelRequired: true,
    label: "family",
    shape: "inline",
    placeholder: "family",
    name: "nameTwo",
    validation: {
      required: true,
      minLength: 8,
    },
    size: 6,
  },
  {
    id: 7,
    type: "checkbox",
    label: "Sample",
    shape: "checkbox",
    placeholder: "placeholder",
    name: "checkbox_btn",
    data: [
      {
        id: 41,
        inputId: "inline-form-1",
        label: "1",
      },
    ],
    size: 12,
  },

];
Run Code Online (Sandbox Code Playgroud)

基于模型创建表单的map方法:

const Sample = () => {
  const {
    register,
    handleSubmit,
    formState: { errors },
    reset,
  } = useForm({
    mode: "onBlur",
  });

  const submitHandler = (data, e) => {
    e.target.reset();
    console.log(data);

    reset();
  };

  const mapForm = formData.map((item) => {
    if (item.shape === "inline") {
      return (
        <InputContainer
          key={item.id}
          register={{
            ...register(item.name, {
              required: item.validation.required,
              minLength: item.validation.minLength,
            }),
          }}
          validation={item.validation}
          placeholder={item.placeholder}
          label={item.label}
          size={item.size}
          error={errors[item.name]}
        />
      );
    }
    if (item.shape === "checkbox") {
      return (
        <CheckBoxContainer
          key={item.id}
          label={item.label}
          data={item.data}
          register={{ ...register("medium", { required: true }) }}
          error={errors.medium}
        />
      );
    }
  });

  return (
    <Fragment>
      <Breadcrumb parent="Dashboard" title="Default" />

      <Container fluid={true}>
        <Row>
          <Col sm="12">
            <Card>
              <CardHeader>
                <h5>Sample Card</h5>
              </CardHeader>
              <CardBody>
                <Form onSubmit={handleSubmit(submitHandler)}>
                  <Row>{mapForm}</Row>
                  <Button type="submit" className="m-t-40">
                    Submit
                  </Button>
                </Form>
              </CardBody>
            </Card>
          </Col>
        </Row>
      </Container>
    </Fragment>
  );
};

export default Sample;
Run Code Online (Sandbox Code Playgroud)

还有一些用于包装输入的容器组件,例如:

const InputContainer = ({
  id,
  register,
  error,
  label,
  labelRequired,
  size,
  type,
  placeholder,
  validation,
}) => {
  return (
    <Col lg={size} style={{ marginTop: "-10px" }}>
      <FormGroup>
        <Label className={`col-form-label`}>
          {label} {labelRequired && <span></span>}
        </Label>
        <Input
          className="form-control"
          type={type}
          placeholder={placeholder}
          {...register}
        />
        {error && error.type === "required" && (
          <p className="p-16 text-danger">this filed is required</p>
        )}

      </FormGroup>
    </Col>
  );
};

export default InputContainer;
Run Code Online (Sandbox Code Playgroud)

Gab*_*ski 1

我还没有深入研究以找出这是否是由于简单地误用钩子而发生的useForm(),但这就是我所发现的。

根据源码,register()返回如下接口(无关内容省略):

type UseFormRegisterReturn<...> = {
    onChange: ChangeHandler;
    onBlur: ChangeHandler;
    ref: RefCallBack;
    ...
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这意味着只有onChange()和onBlur()事件被注册。onChange()是我们感兴趣的。

经过一些快速测试后,我意识到由于某种未知的原因(可能是浏览器错误?不知道),在某些情况下onChange()使用 . 粘贴文本时不会触发CTRL+V。

幸运的是,常规onInput()事件仍然会触发,因此我们可以使用register.onChange()处理程序简单地定义此事件:

type UseFormRegisterReturn<...> = {
    onChange: ChangeHandler;
    onBlur: ChangeHandler;
    ref: RefCallBack;
    ...
}
Run Code Online (Sandbox Code Playgroud)

如果onInput()已经被使用:

<Input
  className="form-control"
  type={type}
  placeholder={placeholder}
  {...register}
  onInput={register && register.onChange}
  // TypeScript
  // onInput={register?.onChange}
/>
Run Code Online (Sandbox Code Playgroud)