如何使用react-hook-form和useFieldArray在动态表单上使用yup验证



我正在尝试使用react-hook-form的useFieldArrayhook创建一个动态表单。用户应该能够添加或删除字段,从而使其动态。我从本教程中寻找灵感,但是缺少的部分是如何实现对状态的错误验证,这将是一个对象数组:{email: string}[]。(对象将接受更多的键/值对。为简单起见,我省略了其余部分。

我试过使用yup作为验证模式。它看起来像这样:

const schema = yup.array().of(
yup.object().shape({
email: yup.string().email().required(),
}),
)

react-hook的实现是:

import * as yup from 'yup'
import { yupResolver } from '@hookform/resolvers/yup'
import { useForm, useFieldArray, Controller } from 'react-hook-form'
const { register, control, handleSubmit, errors } = useForm({
resolver: yupResolver(schema),
mode: 'onChange',
})
const { fields, append, remove } = useFieldArray({
control,
name: 'users',
})

表单或多或少是根据上面的链接中的教程。

当控制台记录useForm钩子的error对象时,它始终给出一个空对象{}。这似乎行不通。我可能遗漏了什么。问题是什么?

也许您想使用context参数来切换模式?

Context:这个Context对象是可变的,将被注入解析器的第二个参数或Yup验证的上下文对象。

import * as React from "react";
import { useForm } from "react-hook-form";
import * as Joi from "joi";
const validationSchema1 = Joi.object({
username: Joi.string()
.alphanum()
.min(3)
.max(30)
.required()
});
const validationSchema2 = Joi.object({
username: Joi.string()
.alphanum()
.min(3)
.max(30)
.required()
});
const App = () => {
const [schemaContext, setSchemaContext] = useState({ schemaA: false })
const { register, handleSubmit, errors } = useForm({
context: schemaContext, // use the context switch here
resolver: async (data, context) => {
const { error, value: values } = context.is1 ? validationSchema1.validate(data, {
abortEarly: false
}) : validationSchema2.validate(data, {
abortEarly: false
});
return {
values: error ? {} : values,
errors: error
? error.details.reduce((previous, currentError) => {
return {
...previous,
[currentError.path[0]]: currentError
};
}, {})
: {}
};
}
});
const onSubmit = data => {
console.log(data)
};
return (
<div className="App">
<h1>resolver</h1>

<form onSubmit={handleSubmit(onSubmit)}>
<label>Username</label>
<input type="text" name="username" ref={register} />
{errors.username && <p>errors.username.message</p>}
<input type="submit" />
</form>
</div>
);
};

React Hook Form v7

使用动态字段react hook form - usefielarray

import { string, object, array } from 'yup';

const formSchema = {
name: string().required("Name is required").min(7, 'Message'),
};
const schema = object({
test: array()
.of(object().shape(formSchema))
});
export default schema;
const methods = useForm({
resolver: yupResolver(schema),
});

显示错误

<div style={{ fontSize: 14 }}>{errors?.test?.[index]?.name?.message}</div>

我使用useForm钩子的解析器属性方法从表单中字段的值确定我应该使用的验证方案。

下面的代码适用于我的用例,也许它可以帮助你

function formValidatorSchemaByPaymentModalityType(paymentModalityType?: ModalityTypes) {
switch (paymentModalityType) {
case ModalityTypes.CREDIT_CARD:
return creditCardSchemaValidation;
default:
return defaultSchemaValidation;
}
}
const methods = useForm({
resolver: (data, context, options) => {
const validatorSchema = formValidatorSchemaByPaymentModalityType(
data.paymentType.value,
)
return yupResolver(validatorSchema)(data, context, options);
},
});

我认为你应该指定你的数组名。这样的:

{
teammates: yupArray().of(
yupObject().shape({
email: stringSchemaBuilder("Email").email(),
expertise: arraySchemaBuilder(false, "Expertise", true, 2, 5),
})
),
};
where teammates is my array name

我也遇到了同样的问题。我通过参考register规则文档更改控制器名称来解决它!

:

`test[${index}].email`  // incorrect

:后

`test.${index}.email`  // correct
const { register, control, handleSubmit, formState: { errors } } = useForm({. resolver: yupResolver(schema),  mode: 'onChange' })
errors[`users[${index}].email`]

相关内容

  • 没有找到相关文章

最新更新