Yup & React Hook Form:如何验证 onChange 而不是 onSubmit
Yup & React Hook Form: How to validate onChange rather than onSubmit
我有一个 onChange 函数 onNameChange
,它包含一个 valid
变量,该变量应该与名称字段的 yup 验证相匹配。问题是 valid 变量似乎只有在提交表单后才是正确的,而不是在更改名称字段时;我希望它在提交之前有效。
如何在更改名称字段而不是提交时获得正确的值?请注意,我发现了一个类似的 post 但它使用了 Formik,这不是我想要使用的:
Yup 设置:
const schema = Yup.object().shape({
name: Yup.string()
.required("Required")
.min(3, "Enter at least 3 characters")
});
const {
register,
handleSubmit,
setError,
formState: { errors },
trigger
} = useForm({
resolver: yupResolver(schema)
// mode: "onTouched",
// reValidateMode: "onChange"
});
改名功能:
const onNameChange = async ({ target: { value } }) => {
const valid = await trigger("name");
console.log("valid", valid, "value", value);
if (!valid) {
// @todo: bug here? valid only correct after submitting
return;
}
getPokemon(value);
setShowPokemon(false);
};
演示形式:
<form onSubmit={handleSubmit(onSubmit /*, onError*/)}>
<input
{...register("name", { required: true })}
name="name"
placeholder="Enter a pokemon"
onChange={onNameChange}
/>
<button type="submit" onClick={onSubmit}>
Show Pokemon
</button>
{errors.name && <p>{errors.name.message}</p>}
</form>
我在 codesandbox 上做了一个现场演示,应该会有帮助:
https://codesandbox.io/s/react-playground-forked-odwi2?file=/Pokemon.js
谢谢
问题是您在更改名称 <input />
后没有更新 RHF 状态,因为您覆盖了从 {...register('name')}
返回的 onChange
属性。
所以基本上你必须在这里选择:
- 使用
setValue
在 onNameChange
回调 中更新 name
的 RHF 状态值
- 使用
<Controller />
组件
您可以在 GitHub 上的 discussion 中阅读相关内容。
第二个选项的实现方式 <Controller />
:
<form onSubmit={handleSubmit(onSubmit /*, onError*/)}>
<Controller
name="name"
control={control}
defaultValue=""
render={({ field: { value, onChange, ...field } }) => (
<input
{...field}
onChange={({ target: { value } }) => {
onChange(value);
onNameChange(value);
}}
placeholder="Enter a pokemon"
/>
)}
/>
<button type="submit" onClick={onSubmit}>
Show Pokemon
</button>
{errors.name && <p>{errors.name.message}</p>}
</form>
我有一个 onChange 函数 onNameChange
,它包含一个 valid
变量,该变量应该与名称字段的 yup 验证相匹配。问题是 valid 变量似乎只有在提交表单后才是正确的,而不是在更改名称字段时;我希望它在提交之前有效。
如何在更改名称字段而不是提交时获得正确的值?请注意,我发现了一个类似的 post 但它使用了 Formik,这不是我想要使用的:
Yup 设置:
const schema = Yup.object().shape({
name: Yup.string()
.required("Required")
.min(3, "Enter at least 3 characters")
});
const {
register,
handleSubmit,
setError,
formState: { errors },
trigger
} = useForm({
resolver: yupResolver(schema)
// mode: "onTouched",
// reValidateMode: "onChange"
});
改名功能:
const onNameChange = async ({ target: { value } }) => {
const valid = await trigger("name");
console.log("valid", valid, "value", value);
if (!valid) {
// @todo: bug here? valid only correct after submitting
return;
}
getPokemon(value);
setShowPokemon(false);
};
演示形式:
<form onSubmit={handleSubmit(onSubmit /*, onError*/)}>
<input
{...register("name", { required: true })}
name="name"
placeholder="Enter a pokemon"
onChange={onNameChange}
/>
<button type="submit" onClick={onSubmit}>
Show Pokemon
</button>
{errors.name && <p>{errors.name.message}</p>}
</form>
我在 codesandbox 上做了一个现场演示,应该会有帮助:
https://codesandbox.io/s/react-playground-forked-odwi2?file=/Pokemon.js
谢谢
问题是您在更改名称 <input />
后没有更新 RHF 状态,因为您覆盖了从 {...register('name')}
返回的 onChange
属性。
所以基本上你必须在这里选择:
- 使用
setValue
在onNameChange
回调 中更新 - 使用
<Controller />
组件
name
的 RHF 状态值
您可以在 GitHub 上的 discussion 中阅读相关内容。
第二个选项的实现方式 <Controller />
:
<form onSubmit={handleSubmit(onSubmit /*, onError*/)}>
<Controller
name="name"
control={control}
defaultValue=""
render={({ field: { value, onChange, ...field } }) => (
<input
{...field}
onChange={({ target: { value } }) => {
onChange(value);
onNameChange(value);
}}
placeholder="Enter a pokemon"
/>
)}
/>
<button type="submit" onClick={onSubmit}>
Show Pokemon
</button>
{errors.name && <p>{errors.name.message}</p>}
</form>