在Yup测试函数中返回true不能清除react-hook-form formState中先前的错误消息



Repo复制问题:https://codesandbox.io/s/yup-react-hook-form-material-checkbox-5dqbm

我正在工作的一个形式,我与反应挂钩的形式和yup创建。我有一个复选框组,我试图要求至少一个复选框被选中提交之前。我用Material UI创建了一个复选框组,并使用yup测试函数处理验证。

下面是显示结构的默认值。

const defaultValues = {
companyName: "",
singleCheckbox: false,
multiCheckbox: { option1: false, option2: false }
};

这是我的yup验证。基本上,我正在检查multiCheckbox的一个选项是否为真,返回真,否则返回假。

const yupSchema = yup.object().shape({
companyName: yup.string().required("Company name is required"),
singleCheckbox: yup.boolean().test("singleCheckbox", "Required", (val) => {
console.log(val, "yup singleCheckbox result");
return val;
}),
multiCheckbox: yup
.object()
.shape({
option1: yup.boolean(),
option2: yup.boolean()
})
.test(
"multiCheckbox",
"At least one of the checkbox is required",
(options) => {
console.log(
options.option1 || options.option2,
"yup multiCheckbox result"
);
return options.option1 || options.option2;
}
)
});

问题:当我点击"提交"按钮而不填写任何字段时,我看到了我应该看到的所有错误信息。当我开始填写输入表单并单击单个复选框时,错误信息消失,但多复选框的错误信息不会消失。

首先,我认为测试函数有问题,这就是为什么我对singleCheckbox也实现了相同的逻辑。singleCheckbox按预期工作,但multiCheckbox不是,即使测试函数yup返回true。

我尝试过的:我试图将useForm的重新验证值更改为onBlur和onChange,但它没有为我工作。

观察:点击Submit按钮会显示所有的错误信息。在选择multiCheckbox的其中一个选项并再次点击提交按钮后,清除multiCheckbox的错误信息。因此,我假设在yup验证和反应-钩子形式验证之间存在脱节。但是为什么同样的断开没有发生在单个singleCheckbox?

我找到了一个解决方法。也许有人会用它。

创建clearErrors函数的ref,并将其传递给返回模式的函数,以便在测试通过时清除错误。

在模式测试中,你不能使用箭头函数,因为你需要this值来获取字段路径。

const getSchema = (clearErrors) => yup.object().shape({
companyName: yup.string().required("Company name is required"),
singleCheckbox: yup.boolean().test("singleCheckbox", "Required", (val) => {
console.log(val, "yup singleCheckbox result");
return val;
}),
multiCheckbox: yup
.object()
.shape({
option1: yup.boolean(),
option2: yup.boolean()
})
.test(
"multiCheckbox",
"At least one of the checkbox is required",
function (this, options) {
console.log(
options.option1 || options.option2,
"yup multiCheckbox result"
);
if (options.option1 || options.option2) {
clearErrors(this.path);
return true;
}
return false;
}
)
});

const copiedClearErrors = useRef();

const formMethods = useForm({
resolver: yupResolver(getSchema(copiedClearErrors.current))
});
useEffect(() => {
copiedClearErrors.current = formMethods.clearErrors;
}, [formMethods.clearErrors]);

最新更新