带有 Formik 和 Stepper 的动态表单想要访问第一步而不是最后一步并抛出 TypeError为什么?

问题描述

我将要使用 formik 构建一个表单来创建客户。有一堆数据要输入,为什么我决定用 Stepper ('@material-ui/core/stepper') 来制作它。 现在表单是动态的,这意味着根据步骤显示不同的表单页面。 对于每个子表单/步骤,我都创建了一个新组件。我明确地将 <form onSubmit=formik.handleSubmit></form> 组件包裹在我的 Stepper 周围,因此与我的子表单的通信沿着道具和回调运行。

所以我的计划是使用 Stepper 中的“下一步”按钮作为提交按钮,在我的“onSubmit”函数的每一步之后缓存子表单条目,并在最后一步将所有数据发送到我的 API。

我还没有完全完成 jet,但每次进入最后一步时都会出现此错误消息:

TypeError: Cannot read property 'company' of undefined
    at C (CustomerStep.js:87)
...

Warning: An unhandled error was caught from submitForm() TypeError: Cannot read property 'company' of undefined
    at C (CustomerStep.js:87)
...

CustomerStep.js:87 是将“value={props.values.company}”设置为我的 TextField 的道具的行。

这很令人困惑,因为我在第一步之后不再输入组件“CustomerStep.js”。子表单中的数据被写入我的 StepperForm.js 中的“数据”状态,所以我真的没有收到错误

这是我的一些代码

StepperForm.js

export default function StepperForm() {

    const[data,setData] = React.useState({
        customer: {
            
        },contacts: [],locations: [],});
...
// other states and attributes
...

    const formik = useFormik({
        initialValues: {
            customer: {
                company: "",street: "",houseNumber: "",plz: "",location: "",country: "",homepage: "",}
        },validationSchema: validation,onSubmit: (values) => {
            cacheData(values);
            handleNext();

            //only submit on last step
            if(activeStep === steps.length) {   
                customerToAPI();
            }
        }
    });

    function getStepContent(step) {
        switch (step) {
            case 0:
                return <CustomerStep 
                    form={formik} 
                    values= {formik.values.customer}
                    touched={formik.touched.customer ? formik.touched.customer : formik.touched}
                    errors={formik.errors.customer ? formik.errors.customer : formik.errors} 
                    handleChange={formik.handleChange}
                />;
            case 1:
                return <ContactStep />; 
            case 2:
                return <LocationStep />;
            case 3:
                return <CheckStep />;
            default:
                return 'unkNown step';
        }
    };

    const cacheData = (values) => {
        let newData = data;
        switch(activeStep) {
            case 0:
                newData.customer = values.customer;
                break;
            case 1:
                // not implemented jet
                // newData.customer = values.customer;
                break;
            case 2:
                // not implemented jet
                // newData.customer = values.customer;
                break;
            default:
                break;
        }
        setData(newData);
    }

    const handleNext = () => {
        let newSkipped = skipped;
        if (isstepSkipped(activeStep)) {
        newSkipped = new Set(newSkipped.values());
        newSkipped.delete(activeStep);
        }

        setActiveStep((prevActiveStep) => prevActiveStep + 1);
        setSkipped(newSkipped);
    };

...
// other Stepper functions
...

    return (
        <div className={classes.root}>
            <form onSubmit={formik.handleSubmit}>
                <Stepper activeStep={activeStep}>
                    {steps.map((label,index) => {
                    const stepProps = {};
                    const labelProps = {};
                    if (isstepOptional(index)) {
                        labelProps.optional = <Typography variant="caption">(optional)</Typography>;
                    }
                    if (isstepSkipped(index)) {
                        stepProps.completed = false;
                    }
                    return (
                        <Step key={label} {...stepProps}>
                        <StepLabel {...labelProps}>{label}</StepLabel>
                        </Step>
                    );
                    })}
                </Stepper>
                <div>
                    {activeStep === steps.length ? (
                    <div>
                        <Typography className={classes.instructions}>
                        Customer created.
                        </Typography>
                        <Button onClick={handleReset} className={classes.button}>
                        Reset
                        </Button>
                    </div>
                    ) : (
                    <div>
                        <div className={classes.instructions}>{getStepContent(activeStep)}</div>
                        <div>
                        <Button disabled={activeStep === 0} onClick={handleBack} className={classes.button}>
                            Back
                        </Button>
                        {isstepOptional(activeStep) && (
                            <Button
                            variant="contained"
                            color="primary"
                            onClick={handleSkip}
                            className={classes.button}
                            >
                            Skip
                            </Button>
                        )}
                        <Button
                            name="submit"
                            variant="contained"
                            color="primary"
                            type="submit"
                            className={classes.button}
                        >
                            {activeStep === steps.length - 1 ? 'Create customer' : 'Next step'}
                        </Button>
                        </div>
                    </div>
                    )}
                </div>
            </form>
        </div>
    );
}

CustomerStep.js

function CustomerStep(props) {
  return (
      <Box>
        <TextField
          className={style.Box}
          id="inputCompany"
          name="customer.company" 
          label="Firmierung"
          onChange={props.handleChange}
          value={props.values.company} 
          error={props.touched.company && Boolean(props.errors.company)}
          helperText={props.touched.company && props.errors.company}
        />

       <TextField 
            className={style.Box} 
            id="inputStreet" 
            name="customer.street"
            label="Straße" 
            onChange={props.handleChange} 
            //value={props.values.street} 
            error={props.touched.street && Boolean(props.errors.street)}
            helperText={props.touched.street && props.errors.street}
        />

        <TextField ... />

        ...
        // some more form stuff,same/similar props

      </Box>
  );
}

export default CustomerStep;

我希望代码不要太多,有人知道发生了什么,也许可以提供帮助。

干杯皮特

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...