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

React(Next.js)中H5P实例重复致xAPI事件触发两次求助

H5P-Standalone xAPI事件重复触发的问题与解决办法

问题原因

  1. 事件监听器未清理:每次useEffect因依赖变化触发时,都会调用fireCompleteH5PTopic给H5P.externalDispatcher绑定新的xAPI事件监听器,但旧的监听器没有被移除。H5P的externalDispatcher是全局单例,旧实例的监听器会一直留存,导致事件触发时多个监听器同时执行。
  2. DOM清理不彻底:removeAllChildNodes仅清除了容器内的DOM节点,但并未处理H5P的全局事件绑定,监听器依然存在于内存中。

解决办法

1. 让事件绑定函数返回清理方法

修改fireCompleteH5PTopic,使其返回用于移除监听器的函数,同时用函数式更新状态避免闭包问题:

const fireCompleteH5PTopic = (H5P) => {
  const handleXAPIEvent = (event) => {
    if (event?.data?.statement?.result?.completion) {
      // 用函数式更新获取最新的counter值
      setCounter(prevCounter => prevCounter + 1)
      completeH5PTopic(event, session.data.user.id, course.slug, topic)
    }
  }

  H5P.externalDispatcher.on("xAPI", handleXAPIEvent);
  // 返回移除监听器的函数
  return () => H5P.externalDispatcher.off("xAPI", handleXAPIEvent);
}

2. 在useEffect中添加清理逻辑

利用useEffect的清理函数,在组件卸载或依赖项变化时,移除旧的事件监听器:

useEffect(() => {
  let cleanupXAPIListener;

  const initH5p = async (contentLocation) => {
    const { H5P: H5PStandalone } = require('h5p-standalone')
    const h5pPath = `https://cdn.thinkeyschool.com/h5p/${contentLocation}`

    const options = {
      id: 'THINKeyLesson',
      h5pJsonPath: h5pPath,
      frameJs: '/h5p/dist/frame.bundle.js',
      frameCss: '/h5p/dist/styles/h5p.css',
    }

    const element = document.getElementById('h5p_container')
    removeAllChildNodes(element)
    await new H5PStandalone(element, options)

    // 保存清理函数
    cleanupXAPIListener = fireCompleteH5PTopic(H5P)
    setIsLoaderVisible(false)
  }

  initH5p(location)

  // 清理逻辑:在依赖变化或组件卸载时执行
  return () => {
    if (cleanupXAPIListener) {
      cleanupXAPIListener()
    }
    // 可选:如果H5P实例提供销毁方法,可在此调用(如H5P.destroy()),进一步清理资源
  }
}, [location, session.data.user.id, course.slug, topic])

3. 优化状态更新

将setCounter(counter + 1)改为函数式更新setCounter(prev => prev + 1),避免因闭包捕获旧状态值导致的更新错误。


内容的提问来源于stack exchange,提问作者Diego González Cruz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 18:26:02