英文:
Inconsistent error behaviour with Mui DateTimePicker and react-hook-form
问题
以下是您要翻译的内容:
"I have a DateTimePicker component that I'm trying to use in a form controlled by react-hook-form, the validation is really simple, using the disablePast prop on the DateTimePicker to ensure that the date selected is in the future.
The issue is that, for reasons unknown, the error does not persist through the value being changed, even if the new value is also invalid. For example:
- Select tomorrow's date - no error (as it should be)
- Change the selected date to yesterday - disablePast error (as it should be)
- Change the selected date to the day before that - no error, but there should be
It also exhibits a similar behaviour when going back up, e.g:
- Enter in a date for two days ago - error (as it should be)
- Increase the date by one, so the value is yesterday - no error, but there should be
- Increase the date by one again, so the value is today - error, but there shouldn't be
All of this is, of course, assuming that the time selected is after the current time, so "today" being selected is definitely not in the past.
I have a feeling that the 'error state' of the Mui component and react-hook-form are not in sync with each other, but I'm not sure how to fix it.
I've put together a codesandbox here, where the issue can be seen:
https://codesandbox.io/s/reverent-pare-yebckz?file=/src/App.js
And my code is also included here:
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { useForm, useController } from "react-hook-form";
import { DateTimePicker } from "@mui/x-date-pickers/DateTimePicker"; // v6.0.4
import "dayjs/locale/en-gb";
const MyDateTimePicker = ({ name, control, error, setError }) => {
const { field } = useController({ name, control });
const handleError = (reason) => {
console.log(reason);
setError(name, {
type: "custom",
message: reason
});
};
return (
<DateTimePicker
{...field}
label="future date"
disablePast
onError={handleError}
slotProps={{
textField: {
error: !!error,
helperText: error?.message
}
}}
/>
);
};
export default function App() {
const {
control,
handleSubmit,
setError,
formState: { errors }
} = useForm({
mode: "all",
defaultValues: {
datetime: null
}
});
const onSubmit = (data) => console.log(data);
return (
<LocalizationProvider dateAdapter={AdapterDayjs} adapterLocale="en-gb">
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<MyDateTimePicker
name="datetime"
control={control}
error={errors?.datetime}
setError={setError}
/>
</form>
</div>
</LocalizationProvider>
);
}
I feel like I'm losing my mind a little bit with this one, so any assistance would be greatly appreciated. Thank you
edit: It seems like setError
is perhaps the problem. How, then, can I connect Mui's validation to react-hook-form's validation so they work together?"
英文:
I have a DateTimePicker component that I'm trying to use in a form controlled by react-hook-form, the validation is really simple, using the disablePast prop on the DateTimePicker to ensure that the date selected is in the future.
The issue is that, for reasons unknown, the error does not persist through the value being changed, even if the new value is also invalid. For example:
- Select tomorrow's date - no error (as it should be)
- Change the selected date to yesterday - disablePast error (as it should be)
- Change the selected date to the day before that - no error, but there should be
It also exhibits a similar behaviour when going back up, e.g:
- Enter in a date for two days ago - error (as it should be)
- Increase the date by one, so the value is yesterday - no error, but there should be
- Increase the date by one again, so the value is today - error, but there shouldn't be
All of this is, of course, assuming that the time selected is after the current time, so "today" being selected is definitely not in the past.
I have a feeling that the 'error state' of the Mui component and react-hook-form are not in sync with each other, but I'm not sure how to fix it.
I've put together a codesandbox here, where the issue can be seen:
https://codesandbox.io/s/reverent-pare-yebckz?file=/src/App.js
And my code is also included here:
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { useForm, useController } from "react-hook-form";
import { DateTimePicker } from "@mui/x-date-pickers/DateTimePicker"; // v6.0.4
import "dayjs/locale/en-gb";
const MyDateTimePicker = ({ name, control, error, setError }) => {
const { field } = useController({ name, control });
const handleError = (reason) => {
console.log(reason);
setError(name, {
type: "custom",
message: reason
});
};
return (
<DateTimePicker
{...field}
label="future date"
disablePast
onError={handleError}
slotProps={{
textField: {
error: !!error,
helperText: error?.message
}
}}
/>
);
};
export default function App() {
const {
control,
handleSubmit,
setError,
formState: { errors }
} = useForm({
mode: "all",
defaultValues: {
datetime: null
}
});
const onSubmit = (data) => console.log(data);
return (
<LocalizationProvider dateAdapter={AdapterDayjs} adapterLocale="en-gb">
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<MyDateTimePicker
name="datetime"
control={control}
error={errors?.datetime}
setError={setError}
/>
</form>
</div>
</LocalizationProvider>
);
}
I feel like I'm losing my mind a little bit with this one, so any assistance would be greatly appreciated. Thank you
edit: It seems like setError
is perhaps the problem. How, then, can I connect Mui's validation to react-hook-form's validation so they work together?
答案1
得分: 1
已解决,完全取消setError
,并将自己的验证作为react-hook-form的规则的一部分编写。
工作示例:https://codesandbox.io/s/eloquent-kowalevski-0qdnyt?file=/src/App.js
英文:
Fixed it by ditching setError
entirely and writing my own validation as part of react-hook-form's rules.
Working example: https://codesandbox.io/s/eloquent-kowalevski-0qdnyt?file=/src/App.js
答案2
得分: -1
在这里,您从父组件获取了props中的setError,因此它不会立即更新错误状态。
不应直接传递setState,因为根据文档,setState函数不会立即更改状态。
您可以查看以下内容:
在React中可以从一个组件将setState作为props传递给另一个组件并从子组件更改父组件状态吗?
英文:
Here, you got the setError as props from the parent component hence it isn't updating the error state immediately.
You shouldn't pass the setState directly, as the setState function will not change the state immediately according to the Documentation.
You can check out the following:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论