通过将错误消息传递给<SelectBirthDay /> 中的onChange 处理程序,您非常接近。
我认为一个不错的选择是将您的日期选择作为一个组件分开,然后在那里处理信息消息。通过这种方式,它与 <Form /> 组件分离,后者不必为用户知道此信息消息,因为它实际上不是表单字段的验证消息。
我还建议将年份的生成移至<SelectBirthYear /> 组件。
<SelectBirthDate />
import { useState } from "react";
import { SelectBirthDay } from "./SelectBirthDay";
import { SelectBirthMonth } from "./SelectBirthMonth";
import { SelectBirthYear } from "./SelectBirthYear";
export const SelectBirthDate = ({ onChange, ...field }) => {
const [invalidMessage, setInvalidMessage] = useState();
const handleChange = (value, invalidMessage) => {
onChange(value);
setInvalidMessage(invalidMessage);
};
return (
<>
<div className="sm:col-span-2 grid grid-cols-3 gap-4 mb-2">
<div className="mt-1">
<SelectBirthYear onChange={handleChange} {...field} />
</div>
<div className="mt-1">
<SelectBirthMonth onChange={handleChange} {...field} />
</div>
<div className="mt-1">
<SelectBirthDay onChange={handleChange} {...field} />
</div>
</div>
<span className="mt-2 text-sm text-gray-500">{invalidMessage}</span>
</>
);
};
<SelectBirthDay />
export const SelectBirthDay = ({ value, onChange }) => {
const handleChange = (date) => onChange(set(value, { date: date.getDate() }));
const days = eachDayOfInterval({
start: startOfMonth(value),
end: endOfMonth(value)
});
useEffect(() => {
if (!isOlderThen18Years(value)) {
onChange(
set(new Date(), { year: getYear(value) }),
"Selected Date was not older then 18 years - automatically reset to the earliest possible date"
);
}
}, [value, onChange]);
return ...
<Form />
<Controller
control={control}
name="birthdate"
rules={{ validate }}
render={({ field: { ref, ...field } }) => (
<SelectBirthDate {...field} />
)}
/>
{errors.birthdate && (
<span className="text-xs text-red-700">
{errors.birthdate.message}
</span>
)}