如何通过中间函数将Formik表单值传递给handleSubmit事件
问题原因
你当前代码拿不到最新表单值、确认逻辑不符合预期,核心是三个写法错误:
- 直接把
handleSubmit绑给确认框的确认回调,完全绕开了Formik的提交流程,Formik不会把最新表单值传给脱离流程调用的方法 - 你误把Formik
onSubmit的第一个参数当成了初始值,实际上这个参数永远是Formik维护的当前实时表单值,只有通过Formik自带的提交方法触发时才能正确拿到 - 下拉选择框上硬写了
value={campusID},强制绑定外部状态,直接绕开Formik的状态管理,用户选择的值不会同步到Formik的表单值中
实现逻辑
- 点击Email按钮时仅打开确认弹窗,不触发任何提交动作
- 用户在弹窗点击「确认/保存」时,调用Formik提供的
submitForm()方法触发正式提交,此时Formik会自动完成表单校验、收集用户编辑后的最新值传入handleSubmit - 用户点击取消时直接关闭弹窗,不触发任何提交逻辑
- 所有表单字段值交给Formik统一管理,不要在Field上硬写value属性绑定外部状态,避免状态不同步
修正后的核心代码
const [formValues, setFormValues] = useState({ emailMessageText: emailMessage, primaryCampusID: 0 // 下拉框初始值同步放入Formik初始值 }); const [confirmOpen, setConfirmOpen] = useState(false); // 注意:第一个参数就是Formik维护的最新表单值,不是初始值 const handleSubmit = (values, { setSubmitting }) => { let req = { campusID: values.primaryCampusID, // 直接从Formik values中取选择的校区值,不要用外部campusID变量 messageText: values.emailMessageText // 这里拿到的就是用户编辑后的最新邮件内容 }; // 此处写接口提交逻辑 // 请求结束后记得调用 setSubmitting(false) }; <Formik enableReinitialize initialValues={formValues} onSubmit={handleSubmit} > {({ submitForm, handleBlur, isSubmitting, isValid, touched, values, errors, }) => ( {/* 用空标签包裹多个根节点,让确认框能访问Formik内部方法 */} <> <Form> <div> <Grid container direction="row" justify="center" alignItems="center" > <Grid item lg={3} md={5} xs={12}> <FormControl fullWidth> <InputLabel htmlFor="primaryCampusID"> Campus </InputLabel> {/* 移除硬写的value={campusID},交给Formik接管字段状态 */} <Field component={Select} type="text" name="primaryCampusID" validate={handleCampusSelection} inputProps={{ id: "primaryCampusID", }} > <MenuItem value={0} key={0}> Select Campus... </MenuItem> {campuses.map((option) => ( <MenuItem value={option.value} key={option.value} > {option.key} </MenuItem> ))} </Field> <FormHelperText error> <ErrorMessage name="primaryCampusID" /> </FormHelperText> </FormControl> </Grid> <Grid container item lg={12} md={12} xs={12} spacing={5} justify="space-between" className={classes.rowSpacing} > <Grid item lg={12} md={12} xs={12}> <FormControl fullWidth> <Field component={TextField} multiline fullWidth={true} validate={validateData} placeholder="Email Message" name="emailMessageText" rows="15" ></Field> <FormHelperText error> <ErrorMessage name="emailMessageText" /> </FormHelperText> </FormControl> </Grid> <Grid item lg={12} md={12} xs={12}> <Button variant="contained" color="primary" size="medium" className={classes.buttonGreen} startIcon={<EmailIcon />} disabled={!isFormDataValid} onClick={() => { // 点击按钮仅打开确认框,不触发提交 setConfirmOpen(true); }} > Email </Button> </Grid> </Grid> </Grid> </div> </Form> {/* 确认框移到Formik内部,onConfirm不要直接传handleSubmit,改为调用submitForm触发正式提交 */} <ConfirmDialog title="Send Notification emails?" open={confirmOpen} setOpen={setConfirmOpen} onConfirm={() => { submitForm(); }} > <Typography style={{ whiteSpace: "pre-line" }}> {`This job will send notice emails to ${currentPermitHolders.length} members.\n\n This is a non reversible action. Do you still want to Proceed with the submission?`} </Typography> </ConfirmDialog> </> )} </Formik>
内容的提问来源于stack exchange,提问作者Dev
相关产品推荐
相关产品推荐

