我正在为我的应用程序评估react hook表单。
我正试图找到一种方法,以react钩子的形式将动态值发送到自定义验证函数。
我们使用的是一个库,该库反过来使用MUI,因此我们必须使用来自react钩子形式的Controller组件。
我想创建一个具有通用函数的通用验证规则文件,我将在多个表单中使用该文件。为了实现这一点,我需要将一些值传递给validate选项中定义的函数。
例如,对于minMaxRule验证,我需要定义一个通用函数,该函数将接受min和max作为参数。我可以看到,用于验证的react钩子表单的类型文件将只有一个带有该字段值的回调。还有其他方法可以做到这一点吗?
表单组件
import React, { BaseSyntheticEvent } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { ruleSet } from '../../utils/validation/rules';
import { Validate, FieldValues } from 'react-hook-form';
export const ReactHookFormSample = (): JSX.Element => {
const { handleSubmit, control, formState: { errors }, getValues, register } = useForm({
mode: "onChange"
});
/**
* Call back on successful submit of form with form values
* @param data
* @param e
*/
const onSubmit = (data: any, e: BaseSyntheticEvent) => {
console.log('hook form', data);
}
/**
* Callback when form is submitted with errors
* @param errors
* @param e
*/
const onError = (errors: any, e: BaseSyntheticEvent) => {
console.log('When errors form', errors);
}
const getError = (field: FieldValues) => {
let errorStr = '';
let inputName = field?.name;
if (errors && errors?.[inputName]) {
errorStr = errors?.[inputName]?.message;
}
return errorStr;
}
return (
<>
<h3>Sample React hook form</h3>
<form onSubmit={handleSubmit(onSubmit, onError)}>
<Controller
name="user_name"
control={control}
rules={{ validate: {isRequired: ruleSet.isRequired, minLen: ruleSet.minLen, maxLen: ruleSet.maxLen } }}
render={({ field, fieldState: {error}, formState }) =>
<MyTextField placeholder="Enter user name here" error={!!error} {...field} />
}
/>
<br/>
<Controller
name="password"
control={control}
rules={{ validate: {isRequired: ruleSet.isRequired, minLen: ruleSet.minLen, maxLen: ruleSet.maxLen } }}
render={({ field, fieldState: {error}, formState }) =>
<MyTextField placeholder="Enter password here" error={!!error} {...field} />
}
/>
<br/>
<Controller
name="retype_password"
control={control}
rules={{ validate: {isRequired: ruleSet.isRequired, minMaxLen: ruleSet.minMaxLen, ruleSet.isValueEqual } }}
render={({ field, fieldState: {error}, formState }) =>
<MyTextField placeholder="Retype password here" error={!!error} {...field} />
}
/>
<br/>
<MyButton color="primary" type="submit">
Submit Form
</MyButton>
</form>
</>
);
};
通用规则文件
export const isRequired = (value: string) => {
return value ? true : 'This is a required input, can not escape';
}
export const maxLen = (value: string) => {
// console.log('Get values', getValues());
return value.length <= 15 || 'Value cannot be more than 15 chars';
}
const minLen = (value: string) => {
// console.log('Get values', getValues());
return value.length >= 7 || 'Value cannot be less than 7 chars';
}
const minMaxLen = (value: string) => { // Here i want to get dynamic parameter for min and max so that it can be used in various forms
return value.length >= <SomeMinValue> && value.length <= <SomeMaxValue> || 'Should be between ${SomeMinValue} and ${SomeMaxValue} chars';
}
const isValueEqual = (value: string) => {
const valOfFieldToBeComparedWith = getValues('password'); // Check how to pass params dynamically to validate function
console.log("retype password is", valOfFieldToBeComparedWith);
return value === valOfFieldToBeComparedWith || 'Password and retype password do not match';
}
export const ruleSet = {
isRequired,
minLen,
maxLen,
minMaxLen,
isValueEqual
}
我基本上需要一种从表单组件向规则文件中定义的这些函数传递参数的方法。
如有任何指导,我们将不胜感激。谢谢
您可以包装验证函数,以便设置最小/最大参数。
const makeMinMaxLen = (min: number, max: number) => (value: string) => {
return value.length >= min && value.length <= max || 'Should be between ${min} and ${max} chars';
}
<Controller
name="retype_password"
control={control}
rules={{ validate: {isRequired: ruleSet.isRequired, minMaxLen: ruleSet.makeMinMaxLen(4, 16), ruleSet.isValueEqual } }}
render={({ field, fieldState: {error}, formState }) =>
<MyTextField placeholder="Retype password here" error={!!error} {...field} />
}
/>
更好的方法是将合成函数存储在渲染函数之外