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

如何等待Strapi CMS返回ID后再执行发送邮件操作?

解决Apollo Client保存数据后等待ID返回再发送邮件的问题

我有个函数负责把数据保存到Strapi CMS,保存后会生成一个ID,我想用这个ID调用发送邮件的函数。但现在的问题是,用户点击按钮后,数据先发送到CMS,但还没等ID返回就执行了发邮件操作,导致第一次点击时ID是undefined;第二次点击时ID已经存在,邮件就能正常发送。我的需求是等ID可用后再执行发邮件操作。


现有代码

1. Apollo Client保存数据并获取ID的代码

const [newID, setNewID] = useState<number>();

const [addProject, { loading }] = useMutation(PROJECT_MUTATION, {
  onCompleted(data) {
    setSubmitted(true);
    setNewID(data.createdProject.data.id); // 在这里获取到ID
  },
  onError() {
    setError(true);
  },
});

useEffect(() => {
  if ( imageUploaded ) {
    addProject({
      variables: {
        title: formData.uploaderMail
      },
  })
    .catch((error) => {
      setError(true);
    })
    .then(() => {
      setSubmitted(true);
     });
   }
  }, [ addProject, formData.uploaderMail]);

2. 尝试用ID发送邮件的代码

const sendDEmailHandleClick = useCallback(() => {
  if (newID && formData.uploaderMail) {
    sendEmail(
      formData.uploaderMail,
      newID // 第一次点击时这里的ID是undefined
    );
    setEmailError("");
  } else {
    setEmailError("Something went wrong");
  }
}, [ formData.uploaderMail, newID ]);

3. 发送邮件工具函数

const sendEmail = async (uploaderMail, id) => {
  const sendEmail = await fetch(
    `/api/req/${uploaderMail}/${id}`,
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
    }
  );
};

4. 发送邮件按钮

<Button
  type="submit"
  onClick={sendDEmailHandleClick}
>
  Send email
</Button>

解决方案

方法一:在Mutation完成后直接触发邮件发送

onCompleted会在数据保存成功、ID返回时触发,直接在这里调用发邮件函数,无需依赖状态更新的延迟:

修改useMutation配置:

const [addProject, { loading }] = useMutation(PROJECT_MUTATION, {
  onCompleted(data) {
    setSubmitted(true);
    const newID = data.createdProject.data.id;
    setNewID(newID);
    // 直接调用发邮件逻辑
    if (formData.uploaderMail) {
      sendEmail(formData.uploaderMail, newID);
      setEmailError("");
    } else {
      setEmailError("邮箱地址无效");
    }
  },
  onError() {
    setError(true);
    setEmailError("数据保存失败,无法发送邮件");
  },
});

调整按钮逻辑,让按钮先触发数据保存(未保存时):

const sendDEmailHandleClick = useCallback(() => {
  // 未保存数据时先触发保存
  if (!newID && imageUploaded) {
    addProject({
      variables: {
        title: formData.uploaderMail
      },
    }).catch(() => {
      setError(true);
      setEmailError("数据保存失败");
    });
  } else if (newID && formData.uploaderMail) {
    // 已有ID直接发邮件
    sendEmail(formData.uploaderMail, newID);
    setEmailError("");
  } else {
    setEmailError("请先完成数据上传");
  }
}, [ addProject, formData.uploaderMail, newID, imageUploaded ]);

方法二:监听newID变化自动触发邮件

用useEffect监听newID的更新,当ID变为有效值时自动发送邮件:

useEffect(() => {
  if (newID && formData.uploaderMail) {
    sendEmail(formData.uploaderMail, newID);
    setEmailError("");
  } else if (newID) {
    setEmailError("邮箱地址无效");
  }
}, [newID, formData.uploaderMail]);

此时按钮只需负责触发数据保存:

const sendDEmailHandleClick = useCallback(() => {
  if (imageUploaded) {
    addProject({
      variables: {
        title: formData.uploaderMail
      },
    }).catch(() => {
      setError(true);
      setEmailError("数据保存失败");
    });
  } else {
    setEmailError("请先完成图片上传");
  }
}, [ addProject, formData.uploaderMail, imageUploaded ]);

方法三:禁用按钮直到ID可用

在UI层面限制,当newID不存在或数据正在保存时禁用按钮,避免用户过早点击:

<Button
  type="submit"
  onClick={sendDEmailHandleClick}
  disabled={!newID || loading}
>
  {loading ? "保存中..." : "Send email"}
</Button>

内容的提问来源于stack exchange,提问作者FD3

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 10:15:43