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

React报错:onTimeUpdate监听器应为函数,实际得到number类型值

问题产生原因

报错的核心原因是你给onTimeUpdate属性传入的值类型不符合要求:

  1. React的事件属性(比如onTimeUpdate)要求接收函数类型的监听器,对应事件触发时React才会调用这个函数。
  2. 你直接写了onTimeUpdate={setTimeout(initProgressBar, 500, {index})},JSX渲染时会立刻执行setTimeout,把它的返回值(定时器的数字ID,number类型)传给onTimeUpdate,自然会触发「期望得到函数、实际拿到数字」的类型错误。
  3. 除此之外你的initProgressBar里还有两个隐藏bug:给开始时间元素赋值时用了currentTime变量,但这个变量是在后面几行才声明的,执行时会触发变量未定义的引用错误;同时每次进度更新都会重复给进度条绑定click监听,会导致点击进度条时多次触发seek逻辑。
修复方案
  • 首先修正onTimeUpdate的传值:把setTimeout逻辑包裹在箭头函数里,把这个箭头函数作为事件监听器传给属性,确保事件触发时才会执行定时器逻辑,而不是渲染时就执行。
  • 调整initProgressBar内部的变量声明顺序,把格式化后当前时间的计算逻辑移到使用它的代码之前,避免引用错误。
  • 给DOM元素访问加判空逻辑,避免音频未加载完成、元素未渲染时访问属性抛出错误,同时加标记避免重复绑定事件。

修正后的代码

Audio标签部分

<audio 
  id={`player-${index}`} 
  onTimeUpdate={() => {
    setTimeout(() => {
      initProgressBar({index})
    }, 500)
  }} 
  src={`http://127.0.0.1:8000${trackUrl}`}
></audio>

initProgressBar函数部分

const initProgressBar = (num) => {
  const player = document.getElementById(`player-${num.index}`);
  // 音频未加载完成时duration为NaN,直接返回等下次更新即可
  if (!player || isNaN(player.duration)) return;

  const length = player.duration;
  const current_time = player.currentTime;
  // 提前计算格式化后的当前时间,移到使用位置之前
  const currentTimeFormatted = calculateCurrentValue(current_time);
  const totalLength = calculateTotalValue(length);

  $(`.end-time-${num.index}`).html(totalLength);
  $(`.start-time-${num.index}`).html(currentTimeFormatted);

  const progressbar = document.getElementById(`seekObj-${num.index}`);
  if (progressbar) {
    progressbar.value = player.currentTime / player.duration;
    // 加标记避免重复绑定click事件
    if (!progressbar.dataset.seekBound) {
      progressbar.addEventListener("click", seek);
      progressbar.dataset.seekBound = "true";
    }
  }

  if (player.currentTime === player.duration) {
    $(`#play-btn-${num.index}`).removeClass("pause");
    $(`#play-btn-${num.index}`).addClass("button");
  }
}

注:React项目中长期混用jQuery、原生DOM操作很容易出现状态不同步、内存泄漏问题,后续可以逐步把DOM操作、事件绑定逻辑改成React状态驱动的写法,稳定性会更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:57:14