React Hook Form dirtyFields returns 不完整/缺失的字段应该是脏的
React Hook Form dirtyFields returns incomplete/ missing field that should be dirty
我的表单 endTimeMins
中的一个字段似乎没有注册到 formState。我有四个字段,所有字段都没有问题,我可以将它们读取为脏但不能读取 endTimeMins
field.Additional 信息,我正在使用 MUI v4 作为我的输入组件。
我以可重用的方式创建了输入字段。总体而言,它呈现 4 个字段。
这是我的startTimeHour/endTimeHour第一。
<Controller
name={`${timeType}Hour`}
control={control}
rules={{ required: true, validate: () => _isEndGreaterThanStart() || errorMsgs.endNotGreater }}
render={({ field: { onChange, value, name, onInputChange } }) => (
<Controls.SingleAutoComplete
name={`${timeType}Hour`}
disableClearable
freeSolo
value={value.toString()}
inputValue={value}
className={classes.autoCompleteInput}
error={!!errors[name]?.message}
options={HOURS_OPTIONS.map((option) => option.value)}
onChange={(e, newValue) => {
onChange(newValue);
_handleStartEndRelation(name, newValue);
}}
onInputChange={(e, newValue) => {
onChange(handleTimeInputs(newValue, 12).toString()); //handle unwanted inputs
_handleStartEndRelation(name, newValue);
}}
/>
)}
/>
这是我的 startTimeMins/endTimeMins
<Controller
name={`${timeType}Mins`}
control={control}
rules={{ required: true }}
render={({ field: { onChange, value, name, onBlur } }) => (
<Controls.SingleAutoComplete
name={`${timeType}Mins`}
options={MINS_OPTIONS.map((option) => option.value)}
getOptionDisabled={(option) => option === MINS_OPTIONS[4].value}
disableClearable
className={classes.autoCompleteInput}
freeSolo
error={!!errors.endTimeHour?.message && name === 'endTimeMins'}
value={value.toString()}
inputValue={value}
onChange={(e, newValue) => {
onChange(newValue);
trigger('endTimeHour');
}}
onInputChange={(e, newValue) => {
onChange(handleTimeInputs(newValue, 59, true).toString());
_handleStartEndRelation(name, handleTimeInputs(newValue, 59, true).toString());
}}
onBlur={() => {
if (value.length === 1) {
onChange(`0${value}`);
_handleStartEndRelation(name, `0${value}`);
}
}}
/>
)}
/>
让我也展示一下处理输入之间关系的函数。这基本上只是在 startTime 的基础上增加 endTime。
const _handleStartEndRelation = (name, value) => {
if (name === 'startTimeHour' && value !== '0') {
if (value === '12') {
setValue('endTimeHour', '1');
} else if (value === '') {
setValue('endTimeHour', '');
} else {
setValue('endTimeHour', +value + 1);
}
}
if (name === 'startTimeMins') {
setValue('endTimeMins', value);
}
trigger('endTimeHour');
};
综上所述,我可以毫无问题地获取或设置字段的值。当我检查 console.log(_getFieldState('endTimeMins').isDirty);
时我的字段 endTime 的 isDirty 状态是否未定义并且当我使用 console.log(dirtyFields);
检查它时它从 dirtyFields 中丢失
我确保我也在 defaultValues 中设置了它。
const {
handleSubmit,
setValue,
getValues,
_getFieldState,
trigger,
control,
reset,
formState: { isDirty, dirtyFields, isValid, errors }
} = useForm({
defaultValues: {
OFIdate: new Date(),
startTimeHour: '',
endTimeHour: '',
startTimeMins: '',
endTimeMins: ''
},
mode: 'onChange'
});
我可能在这里遗漏了什么?我将我的代码字段相互比较,这对我来说并没有什么不同。那为什么会这样呢?
找到解决方案。
setValue('name', 'value', { shouldDirty: true })
我想当我需要用setValue()
设置字段值时,如果它们是脏的,我也必须手动设置。
我的表单 endTimeMins
中的一个字段似乎没有注册到 formState。我有四个字段,所有字段都没有问题,我可以将它们读取为脏但不能读取 endTimeMins
field.Additional 信息,我正在使用 MUI v4 作为我的输入组件。
我以可重用的方式创建了输入字段。总体而言,它呈现 4 个字段。
这是我的startTimeHour/endTimeHour第一。
<Controller
name={`${timeType}Hour`}
control={control}
rules={{ required: true, validate: () => _isEndGreaterThanStart() || errorMsgs.endNotGreater }}
render={({ field: { onChange, value, name, onInputChange } }) => (
<Controls.SingleAutoComplete
name={`${timeType}Hour`}
disableClearable
freeSolo
value={value.toString()}
inputValue={value}
className={classes.autoCompleteInput}
error={!!errors[name]?.message}
options={HOURS_OPTIONS.map((option) => option.value)}
onChange={(e, newValue) => {
onChange(newValue);
_handleStartEndRelation(name, newValue);
}}
onInputChange={(e, newValue) => {
onChange(handleTimeInputs(newValue, 12).toString()); //handle unwanted inputs
_handleStartEndRelation(name, newValue);
}}
/>
)}
/>
这是我的 startTimeMins/endTimeMins
<Controller
name={`${timeType}Mins`}
control={control}
rules={{ required: true }}
render={({ field: { onChange, value, name, onBlur } }) => (
<Controls.SingleAutoComplete
name={`${timeType}Mins`}
options={MINS_OPTIONS.map((option) => option.value)}
getOptionDisabled={(option) => option === MINS_OPTIONS[4].value}
disableClearable
className={classes.autoCompleteInput}
freeSolo
error={!!errors.endTimeHour?.message && name === 'endTimeMins'}
value={value.toString()}
inputValue={value}
onChange={(e, newValue) => {
onChange(newValue);
trigger('endTimeHour');
}}
onInputChange={(e, newValue) => {
onChange(handleTimeInputs(newValue, 59, true).toString());
_handleStartEndRelation(name, handleTimeInputs(newValue, 59, true).toString());
}}
onBlur={() => {
if (value.length === 1) {
onChange(`0${value}`);
_handleStartEndRelation(name, `0${value}`);
}
}}
/>
)}
/>
让我也展示一下处理输入之间关系的函数。这基本上只是在 startTime 的基础上增加 endTime。
const _handleStartEndRelation = (name, value) => {
if (name === 'startTimeHour' && value !== '0') {
if (value === '12') {
setValue('endTimeHour', '1');
} else if (value === '') {
setValue('endTimeHour', '');
} else {
setValue('endTimeHour', +value + 1);
}
}
if (name === 'startTimeMins') {
setValue('endTimeMins', value);
}
trigger('endTimeHour');
};
综上所述,我可以毫无问题地获取或设置字段的值。当我检查 console.log(_getFieldState('endTimeMins').isDirty);
时我的字段 endTime 的 isDirty 状态是否未定义并且当我使用 console.log(dirtyFields);
我确保我也在 defaultValues 中设置了它。
const {
handleSubmit,
setValue,
getValues,
_getFieldState,
trigger,
control,
reset,
formState: { isDirty, dirtyFields, isValid, errors }
} = useForm({
defaultValues: {
OFIdate: new Date(),
startTimeHour: '',
endTimeHour: '',
startTimeMins: '',
endTimeMins: ''
},
mode: 'onChange'
});
我可能在这里遗漏了什么?我将我的代码字段相互比较,这对我来说并没有什么不同。那为什么会这样呢?
找到解决方案。
setValue('name', 'value', { shouldDirty: true })
我想当我需要用setValue()
设置字段值时,如果它们是脏的,我也必须手动设置。