如何在使用 react-hook-form 在 React 中引入一个值时重置其他值
How to reset other values when one is introduced in React with react-hook-form
具有此验证架构:
const schema = yup.object().shape({
second: yup.number(),
minute: yup.number(),
triggerName: yup.string().required()
});
triggerName 应该是必需的,但是当我为 minute
输入写一些东西时,second
输入应该重置,反之亦然。
const { handleSubmit, register, reset } = useForm({ resolver: yupResolver(schema) });
...
<Input inputId='second' type='number' {...register('second')} />
<Input inputId='minute' type='number' {...register('minute')} />
<Input inputId='trigger-name' label='triggerName' {...register('triggerName')} />
尝试执行类似以下操作但会引发错误:
<Input inputId='second' type='number' {...reset(), register('second')} />
从 useForm 挂钩导入 setValue
并在输入上设置 onChange 函数
您可以为每个输入执行此操作,并对 onChange
有不同的行为
const {
handleSubmit,
setValue,
register,
reset
} = useForm({ resolver: yupResolver(schema) });
const onChangeMyInput = (e) => {
reset()
setValue('second', e.target.value)
}
<Input
{...register('second')}
onChange={onChangeMyInput}
inputId='second'
type='number'
/>
register
returns 具有以下结构的对象:
{
onChange: function(){},
onBlur: function(){},
ref: function(){}
}
目前您只是传递从 register
函数返回的对象,但您可以向输入的 onChange
添加一些其他功能,如下例所示(这里我们重新设置彼此通过调用 resetField
):
在表单中填写字段
const Input = React.forwardRef(({ inputId, ...otherProps }, ref) => {
return <input id={inputId} ref={ref} {...otherProps} />;
});
const schema = yup.object().shape(
{
second: yup
.number()
.nullable()
.transform((value, originalValue) =>
String(originalValue).trim() === '' ? null : value
),
minute: yup
.number()
.nullable()
.transform((value, originalValue) =>
String(originalValue).trim() === '' ? null : value
),
triggerName: yup.string().required(),
}
);
function TestForm() {
const {
handleSubmit,
register,
formState: { errors },
resetField,
} = useForm({
resolver: yupResolver(schema),
});
console.log(errors);
const onSubmit = (data) => {
if (!data.minute && !data.second) {
alert('on of minute or second field must has value');
return false;
}
alert('success');
console.log(data);
};
const { onChange: onSecondChange, ...secodField } = register('second');
const { onChange: onMinuteChange, ...minuteField } = register('minute');
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Input
inputId="second"
type="number"
{...secodField}
onChange={(e) => {
onSecondChange(e);
resetField('minute');
}}
/>
<Input
inputId="minute"
type="number"
{...minuteField}
onChange={(e) => {
onMinuteChange(e);
resetField('second');
}}
/>
<Input
inputId="trigger-name"
label="triggerName"
{...register('triggerName')}
/>
<input type="submit" value="submit" />
</form>
);
}
我已经验证 minute
或 second
在 onSubmit
函数中具有价值,因为我不完全了解您的业务是否需要填写这两个或其中一个,但是如果您希望可以通过 yup
使用 when
方法或通过在您的架构上定义一些自定义规则来处理此验证。
具有此验证架构:
const schema = yup.object().shape({
second: yup.number(),
minute: yup.number(),
triggerName: yup.string().required()
});
triggerName 应该是必需的,但是当我为
minute
输入写一些东西时,second
输入应该重置,反之亦然。const { handleSubmit, register, reset } = useForm({ resolver: yupResolver(schema) });
...
<Input inputId='second' type='number' {...register('second')} />
<Input inputId='minute' type='number' {...register('minute')} />
<Input inputId='trigger-name' label='triggerName' {...register('triggerName')} />
尝试执行类似以下操作但会引发错误:
<Input inputId='second' type='number' {...reset(), register('second')} />
从 useForm 挂钩导入 setValue
并在输入上设置 onChange 函数
您可以为每个输入执行此操作,并对 onChange
const {
handleSubmit,
setValue,
register,
reset
} = useForm({ resolver: yupResolver(schema) });
const onChangeMyInput = (e) => {
reset()
setValue('second', e.target.value)
}
<Input
{...register('second')}
onChange={onChangeMyInput}
inputId='second'
type='number'
/>
register
returns 具有以下结构的对象:
{
onChange: function(){},
onBlur: function(){},
ref: function(){}
}
目前您只是传递从 register
函数返回的对象,但您可以向输入的 onChange
添加一些其他功能,如下例所示(这里我们重新设置彼此通过调用 resetField
):
const Input = React.forwardRef(({ inputId, ...otherProps }, ref) => {
return <input id={inputId} ref={ref} {...otherProps} />;
});
const schema = yup.object().shape(
{
second: yup
.number()
.nullable()
.transform((value, originalValue) =>
String(originalValue).trim() === '' ? null : value
),
minute: yup
.number()
.nullable()
.transform((value, originalValue) =>
String(originalValue).trim() === '' ? null : value
),
triggerName: yup.string().required(),
}
);
function TestForm() {
const {
handleSubmit,
register,
formState: { errors },
resetField,
} = useForm({
resolver: yupResolver(schema),
});
console.log(errors);
const onSubmit = (data) => {
if (!data.minute && !data.second) {
alert('on of minute or second field must has value');
return false;
}
alert('success');
console.log(data);
};
const { onChange: onSecondChange, ...secodField } = register('second');
const { onChange: onMinuteChange, ...minuteField } = register('minute');
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Input
inputId="second"
type="number"
{...secodField}
onChange={(e) => {
onSecondChange(e);
resetField('minute');
}}
/>
<Input
inputId="minute"
type="number"
{...minuteField}
onChange={(e) => {
onMinuteChange(e);
resetField('second');
}}
/>
<Input
inputId="trigger-name"
label="triggerName"
{...register('triggerName')}
/>
<input type="submit" value="submit" />
</form>
);
}
我已经验证 minute
或 second
在 onSubmit
函数中具有价值,因为我不完全了解您的业务是否需要填写这两个或其中一个,但是如果您希望可以通过 yup
使用 when
方法或通过在您的架构上定义一些自定义规则来处理此验证。