使用 Controller 将输入与 React Hook Form 集成时添加自定义验证

问题描述 投票:0回答:1

我正在尝试使用 React Hook Form 设置自定义输入字段,因此使用 useForm 挂钩,如下所示;

const {
        control,
        handleSubmit,
        register,
        formState,
        setValue,
        getValues
    } = useForm({
        mode: 'onSubmit',
        reValidateMode: 'onSubmit',
        shouldFocusError: true,
        defaultValues: {
            myIdFld: '123'
        },
        resolver: yupResolver(schema)
    });

const onSubmit = (data) => {
        alert(JSON.stringify(data));
    };
    const onErrors = (data) => {
        alert('Errors !');
    };

我有一个字段配置js,如下所示;

let sampleField = {"id":"myIdFld","mandatory":true,"visible":true,"maxLength":5,"items":[],"gridItems":[],"disabled":false,"hidden":false,"readonly":false,"fieldLabel":"My ID 1","pattern":/[A-Za-z]{3}/,"editable":true};

我使用上面的内容并将其传递给我的自定义 Field 组件 JSX,如下所示;

return (
<>
        <form
            onSubmit={handleSubmit((data) => console.log('Save Successful ', data))}>
            <Field name={sampleField.id} control={control} label={sampleField.fieldLabel} formFieldProps={{ necessity: (sampleField.mandatory === true) ?'required': 'optional' }} field={sampleField} {...props} />
      <Button onClick={handleSubmit(onSubmit, onErrors)} type="submit" variant="cta">Submit</Button>
    </form>
</>
)

我的 Field 组件 JSX 如下;

import { Controller } from "react-hook-form"
          
<Controller
    control={control}
    rules={{required: "The field is required"}}
    name={name}
    render={({ field: { ref, ...restField }, fieldState: { error } }) => {
        const validationMessage = error ? error.message : helperText;
        const validationStatus = error && 'error';
        return (
            <FormField validationStatus={validationStatus} {...formFieldProps}>
            <FormFieldLabel {...formFieldLabelProps}>
                {label}
            </FormFieldLabel>
            <Input
                inputRef={ref}
                {...restField}
                {...restProps}
            />
            <FormFieldHelperText>{validationMessage}</FormFieldHelperText>
            </FormField>
        );
    }}
/>        

我的输入是一种自定义控制组件,我正在尝试通过控制器集成

现在,问题是在提交时,我确实收到了在警报文本框中输入的值(这意味着该字段正在注册)。 但我无法添加任何验证,也无法填充错误对象。

请建议我需要在上面的代码中添加什么,以便验证/错误可以 融合的。 理想情况下,我想使用 SampleField 配置 js 进行验证(因为它具有强制属性:true、正则表达式/模式等……不过,我不确定是否还需要提供自定义错误消息。

如果是的话,我不知道在哪里可以添加这些错误配置。

我已经尝试添加以下内容并将rules={createValidationRules(field)}传递给Field;

const createValidationRules = (fieldConfig) => {
        const rules = {};
        if (fieldConfig.mandatory) {
            rules.required = fieldConfig.customRequiredMessage || "This field is required";
        }
        if (fieldConfig.pattern) {            
            rules.pattern = {
                value: fieldConfig.pattern,
                message: fieldConfig.customPatternMessage || "Invalid format"
            };
        }
        if (fieldConfig.maxLength) {
            rules.maxLength = {
                value: fieldConfig.maxLength,
                message: fieldConfig.customMaxLengthMessage || `Maximum length is ${fieldConfig.maxLength}`
            };
        }
        return rules;
    };

但是还是不行。

javascript reactjs react-hooks formik react-hook-form
1个回答
0
投票

目前,您仅静态设置所需的规则。

因此为类似这样的示例设置错误消息(一种干净的方法):

errorMessages: {
  required: "This field is required",
  maxLength: "The input exceeds maximum length",
  pattern: "The input does not match the required pattern"
}

然后在你的控制器中使用它,如下所示:

<Controller
  control={control}
  name={name}
  rules={{
    required: sampleField.mandatory ? sampleField.errorMessages?.required || "This field is required" : false,
    maxLength: sampleField.maxLength ? {
      value: sampleField.maxLength,
      message: sampleField.errorMessages?.maxLength || `Maximum length is ${sampleField.maxLength}`
    } : undefined,
    pattern: sampleField.pattern ? {
      value: sampleField.pattern,
      message: sampleField.errorMessages?.pattern || "Invalid format"
    } : undefined
  }}
  render={({ field: { ref, ...restField }, fieldState: { error } }) => {
    const validationMessage = error ? error.message : helperText;
    const validationStatus = error ? 'error' : undefined;
    return (
      <FormField validationStatus={validationStatus} {...formFieldProps}>
        <FormFieldLabel {...formFieldLabelProps}>
          {label}
        </FormFieldLabel>
        <Input
          inputRef={ref}
          {...restField}
          {...restProps}
        />
        <FormFieldHelperText>{validationMessage}</FormFieldHelperText>
      </FormField>
    );
  }}
/>

现在这是从我自己的代码中挑选出来的,所以请确保它们都适合在一起,因为我没有真正测试它。

© www.soinside.com 2019 - 2024. All rights reserved.