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

React应用中语音录音发送按钮首次点击发送空文件、二次点击才生效问题排查求助

问题原因分析

我一眼就看出问题出在React状态更新的异步特性和你处理发送逻辑的方式上:

  1. 当你点击「发送录音」按钮调用submitNewMessage时,你先执行setAttachFile(audioBlob),然后立刻用attachFile创建请求体{ body: newMessage, attachment: attachFile }。但React的setState是异步的,这时候attachFile还是之前的旧值(初始是undefined),所以第一次发送的是空文件。
  2. 第二次点击时,attachFile已经被更新成上一次录制的audioBlob,所以才能发送正确的文件——这完全是因为异步更新滞后导致的巧合。

另外,你的useRecorder钩子中,dataavailable事件触发后才会设置audioBlob,而stopRecording调用后,MediaRecorder需要一点时间来触发这个事件,但这不是核心问题,核心还是submit函数里的状态使用错误。

解决方案

我们可以直接修复submitNewMessage函数,不用依赖attachFile这个中间状态,直接使用当前最新的audioBlob:

const submitNewMessage = () => {
  // 直接用当前的audioBlob,跳过setAttachFile这一步,避免异步问题
  const body = { body: newMessage, attachment: audioBlob }
  handleUpdateLog(log, newMessage, audioBlob)
  console.log(audioBlob)
  // handleSubmitNewMessage(log.id, body)
}

如果你的业务逻辑确实需要维护attachFile状态,那你需要用useEffect监听attachFile的变化,在它更新后再执行发送逻辑:

// 先修改submit函数,只负责设置状态
const submitNewMessage = () => {
  setAttachFile(audioBlob)
}

// 然后添加useEffect监听attachFile的变化
useEffect(() => {
  if (attachFile) {
    const body = { body: newMessage, attachment: attachFile }
    handleUpdateLog(log, newMessage, attachFile)
    console.log(attachFile)
    // handleSubmitNewMessage(log.id, body)
    // 发送后可以重置状态
    setAttachFile(null)
  }
}, [attachFile, log, newMessage, handleUpdateLog])

另外,建议你在useRecorder里做一点小优化,确保audioBlob初始值是null而不是空字符串,这样判断起来更清晰:

const [audioBlob, setAudioBlob] = useState(null);

这样修改后,第一次点击发送就能直接拿到最新的录制文件,不会再出现空文件的问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 15:17:35