React 将 Formik 表单有效状态传递给父组件

问题描述 投票:0回答:2

在我的 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 表单的验证状态禁用或启用该按钮。我怎样才能实现这个目标?

javascript reactjs typescript formik
2个回答
0
投票

我想你必须改变

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
                        }
                    }}
                />

0
投票

我认为正确的逻辑是每次输入发生变化时根据

errors.email

的存在设置父组件的状态
onChange={() => {
  if(errors.email) {
     setIsFormValid(true);
  }else{
    setIsFormValid(false);
  }
}}
© www.soinside.com 2019 - 2024. All rights reserved.