为什么自定义输入验证和 setError() 在使用 useField() 时不起作用?
Why custom input validation and setError() won't work when using useField()?
我在表格中创建了我面临的问题的最小版本。我想让某些 InputFields 具有最大和最小范围。如果用户键入超出该范围的内容,我将使用 setError()
设置错误字段。但是,验证并不总是有效。例如,如果我在 CGPA 字段中键入 555,我会看到错误,但如果我键入 55 则看不到错误,而我已将范围指定为 0 到 4。
代码沙箱here
您可以为此创建自己的自定义验证函数,这是一个示例
福米克场:
<Field
type="number"
name="myNumber"
placeholder="Please input something"
validate={(event) => Validators.customFieldLevelValidation(event, [Validators.required, Validators.minLength(6), Validators.maxLength(12)])} />
自定义验证器Class:
class Validators {
static customFieldLevelValidation = (value, validations) => {
for (let validation of validations) {
const result = validation(value);
if (result) {
return result;
}
}
return null;
};
static maxLength = max => value =>
value && value.length > max ? `Must be ${max} characters or less` : undefined;
static minLength = min => value =>
value && value.length < min ? `Must be ${min} characters or more` : undefined;
}
按照this and this,我想出了解决办法。诀窍是将一个对象传递给 useField()
而不是像我所做的那样只传递道具。
所以,InputField.tsx
应该是这样的:
function InputField({ color, ...props }: TInputFieldProps) {
const [field, { error }] = useField({
name: props.name,
validate: (value) => {
let message: string = undefined;
if (props.type === "number" && (props.min || props.max)) {
if (parseFloat(value) > parseFloat(props.max as string)) {
message = `The value of ${props.label} cannot be more than ${props.max}`;
}
if (parseFloat(value) < parseFloat(props.min as string)) {
message = `The value of ${props.label} cannot be less than ${props.min}`;
}
}
return message;
},
type: props.type,
});
return (
<FormControl
error={!!error}
style={{ marginTop: "10px", marginBottom: "20px" }}
>
<FormLabel htmlFor={props.name}>{props.label}</FormLabel>
<Input
{...props}
{...field}
id={field.name}
inputProps={{
min: props.min ?? props.min,
max: props.max ?? props.max,
step: props.step ?? props.step,
}}
/>
{error && <FormHelperText error={!!error}>{error}</FormHelperText>}
</FormControl>
);
}
export default InputField;
尽管如此,我仍然不确定为什么 setError()
会出现这样的问题。这可能与陈旧状态有关。
根据我的测试,如果您使用的是 Yup,这不会破坏 Yup 验证,这太棒了。我在这里不能依赖 Yup 的原因是因为 min
和 max
值来自解析我原来问题中的文件上传。
我在表格中创建了我面临的问题的最小版本。我想让某些 InputFields 具有最大和最小范围。如果用户键入超出该范围的内容,我将使用 setError()
设置错误字段。但是,验证并不总是有效。例如,如果我在 CGPA 字段中键入 555,我会看到错误,但如果我键入 55 则看不到错误,而我已将范围指定为 0 到 4。
代码沙箱here
您可以为此创建自己的自定义验证函数,这是一个示例
福米克场:
<Field
type="number"
name="myNumber"
placeholder="Please input something"
validate={(event) => Validators.customFieldLevelValidation(event, [Validators.required, Validators.minLength(6), Validators.maxLength(12)])} />
自定义验证器Class:
class Validators {
static customFieldLevelValidation = (value, validations) => {
for (let validation of validations) {
const result = validation(value);
if (result) {
return result;
}
}
return null;
};
static maxLength = max => value =>
value && value.length > max ? `Must be ${max} characters or less` : undefined;
static minLength = min => value =>
value && value.length < min ? `Must be ${min} characters or more` : undefined;
}
按照this and this,我想出了解决办法。诀窍是将一个对象传递给 useField()
而不是像我所做的那样只传递道具。
所以,InputField.tsx
应该是这样的:
function InputField({ color, ...props }: TInputFieldProps) {
const [field, { error }] = useField({
name: props.name,
validate: (value) => {
let message: string = undefined;
if (props.type === "number" && (props.min || props.max)) {
if (parseFloat(value) > parseFloat(props.max as string)) {
message = `The value of ${props.label} cannot be more than ${props.max}`;
}
if (parseFloat(value) < parseFloat(props.min as string)) {
message = `The value of ${props.label} cannot be less than ${props.min}`;
}
}
return message;
},
type: props.type,
});
return (
<FormControl
error={!!error}
style={{ marginTop: "10px", marginBottom: "20px" }}
>
<FormLabel htmlFor={props.name}>{props.label}</FormLabel>
<Input
{...props}
{...field}
id={field.name}
inputProps={{
min: props.min ?? props.min,
max: props.max ?? props.max,
step: props.step ?? props.step,
}}
/>
{error && <FormHelperText error={!!error}>{error}</FormHelperText>}
</FormControl>
);
}
export default InputField;
尽管如此,我仍然不确定为什么 setError()
会出现这样的问题。这可能与陈旧状态有关。
根据我的测试,如果您使用的是 Yup,这不会破坏 Yup 验证,这太棒了。我在这里不能依赖 Yup 的原因是因为 min
和 max
值来自解析我原来问题中的文件上传。