在我的 typescript 项目中,我有一个 ParentComponent,它有一个 ChildComponent,其中有一个带有 Yup 表单的 Formik,必须在用户输入时进行验证。在 ParentComponent 上,我还有一个下一个按钮,如果用户在表单上键入内容时出现验证错误,则必须禁用该按钮。
这是 ParentComponent 的代码片段:
const [isFormValid, setIsFormValid] = useState<boolean>(true);
const [isNextButtonDisabled, setIsNextButtonDisabled] = useState<boolean>(false);
useEffect(() => {
if(!isFormValid) {
setIsNextButtonDisabled(true);
}
}, [isFormValid]);
const handleNext = () => {
if (!isFormValid) {
return;
}
goNext();
}
return (
<>
<ChildComponent
setIsFormValid={setIsFormValid}
isFormValid={isFormValid}
/>
<CustomButtonComponent
type="submit"
form="myFormikForm"
isDisabled={isNextButtonDisabled}
/>
</>);
这是子组件:
type FormProps = {
isFormValid: boolean;
setIsFormValid: React.Dispatch<React.SetStateAction<boolean>>;
};
export const ChildComponent: React.FC<FormProps> = ({
isFormValid
setIsFormValid,
}) => {
return(
<Formik
initialValues={{email: ''}}
onSubmit={() => {}}
validationSchema={emailValidationSchema}
validateOnChange={true}
validateOnBlur={true}
>
{({ values, errors, handleChange}) => (
<Form
id={"myFormikForm"}
controlId={"myFormikForm"}
value={values.email}
placeholder=""
isInvalid={!!errors.email}
error={errors.email}
onChange={() => {
if(errors.email) {
setIsFormValid(!isFormValid);
}
}}
/>
)}
};
这就是我尝试实现它的方式。表单内值的验证按预期工作,来自 emailValidationSchema 的验证消息在用户键入时正确显示在字段下,但似乎字段“isFormValid”的有效状态不会对 ParentComponent 做出反应,我可以不根据用户键入时 Formik 表单的验证状态禁用或启用该按钮。我怎样才能实现这个目标?
我想你必须改变
setIsFormValid
内部的值。
它将不断改变布尔值。尝试设置 False
不使用否定。
<Form
id={"myFormikForm"}
controlId={"myFormikForm"}
value={values.email}
placeholder=""
isInvalid={!!errors.email}
error={errors.email}
onChange={() => {
if(errors.email) {
setIsFormValid(!isFormValid); // to False
}
}}
/>
我认为正确的逻辑是每次输入发生变化时根据
errors.email
的存在设置父组件的状态
onChange={() => {
if(errors.email) {
setIsFormValid(true);
}else{
setIsFormValid(false);
}
}}