You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过中间函数将Formik表单值传递给handleSubmit事件

问题原因

你当前代码拿不到最新表单值、确认逻辑不符合预期,核心是三个写法错误:

  • 直接把handleSubmit绑给确认框的确认回调,完全绕开了Formik的提交流程,Formik不会把最新表单值传给脱离流程调用的方法
  • 你误把FormikonSubmit的第一个参数当成了初始值,实际上这个参数永远是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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 08:54:22