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

Zoom Meeting SDK集成报错:Uncaught TypeError: c2 is not a function求助

问题:Zoom Web SDK集成React时出现Uncaught TypeError: c2 is not a function错误

我基于React开发了Zoom会议集成功能,支持通过输入会议URL加入会议,并且在会议准入后动态将SpeechText组件渲染到会议底部栏。但运行时控制台抛出Uncaught TypeError: c2 is not a function错误,请求协助排查解决。

相关代码

import React, { useState } from "react";
import ReactDOM from "react-dom";
import { ZoomMtg } from "@zoomus/websdk";
import "./Meet.css";
import SpeechText from "./SpeechText";

ZoomMtg.setZoomJSLib("https://source.zoom.us/2.14.0/lib", "/av");
ZoomMtg.preLoadWasm();
ZoomMtg.prepareWebSDK();
ZoomMtg.i18n.load("en-US");
ZoomMtg.i18n.reload("en-US");

const KJUR = require("jsrsasign");

const Meet = () => {
 var sdkKey = process.env.REACT_APP_SDK_KEY;

 var meetURL = "";
 var meetNo = "";
 var pass = "";
 var role = 0; // 0表示参会者,1表示主持人
 var userName = "NIK";
 var userEmail = "";
 var registrantToken = "";
 var zakToken = "";
 var leaveURL = "https://zoom.us/"; // 会议结束后跳转的地址

 const [ele, setEle] = useState(
 document.getElementsByClassName("footer__btns-container")
 );
 const getSign = (e) => {
 e.preventDefault();
 // 验证会议URL格式
 if (
  !meetURL ||
  !meetURL.match(/^https:\/\/us05web\.zoom\us\/j\/\d+\?pwd=[a-zA-Z0-9]+$/)
 ) {
  alert("请输入有效的会议链接");
  return;
 }

pass = meetURL.split("?")[1].split("=")[1];
meetNo = meetURL.split("?")[0].split("/")[4];
const iat = Math.round(new Date().getTime() / 1000) - 30;
const exp = iat + 60 * 60 * 2;
const oHeader = { alg: "HS256", typ: "JWT" };
const oPayload = {
sdkKey: process.env.REACT_SDK_KEY,
mn: meetNo,
role: role,
iat: iat,
exp: exp,
appKey: process.env.REACT_SDK_KEY,
tokenExp: iat + 60 * 60 * 2,
};
const sHeader = JSON.stringify(oHeader);
const sPayload = JSON.stringify(oPayload);
const signature = KJUR.jws.JWS.sign(
"HS256",
sHeader,
sPayload,
process.env.REACT_SDK_KEY
);
startMeet(signature);
};

const startMeet = (signature) => {
document.getElementById("zmmtg-root").style.display = "block";


ZoomMtg.init({
  leaveUrl: leaveURL,
  success: (success) => {
    ZoomMtg.join({
      signature: signature,
      sdkKey: sdkKey,
      meetingNumber: meetNo,
      passWord: pass,
      userName: userName,
      userEmail: userEmail,
      tk: registrantToken,
      zak: zakToken,
      success: (success) => {
        
        var refreshInterval = setInterval(() => {
          if (document.getElementsByClassName("footer__btns-container")) {
            setEle(
              document.getElementsByClassName("footer__btns-container")
            );
          }
        }, 2000);
        if (ele.length !== 0) {
          const createdEle = document.createElement("div");
          createdEle.setAttribute("id", "custom-foot-bar");
          ele[0].appendChild(createdEle);
          ReactDOM.render(
            <SpeechText />,
            document.getElementById("custom-foot-bar")
          );
          clearInterval(refreshInterval);
        }
        console.log(success);
      },
      error: (error) => {
        console.log(error);
      },
    });
  },
  error: (error) => {
    console.log(error);
  },
});
};

return (
<>
  <main>
    <h1>GPT Zoom Bot</h1>
    <div className="meetCredentials">
      <label>会议URL</label>
      <input
        autoFocus
        type="text"
        id="meetingUrl"
        placeholder="输入会议链接"
        required
        defaultValue={meetURL}
        onChange={(e) => {
          meetURL = e.target.value;
        }}
      />
      <button onClick={getSign}>加入会议</button>
    </div>
  </main>
</>
);
};

export default Meet;

错误排查与修复方案

1. ReactDOM.render版本兼容问题

React 18已移除ReactDOM.renderAPI,改用createRoot,继续使用旧API会触发此类函数未定义错误。
修复步骤:

  • 替换导入语句:
// 原代码
import ReactDOM from "react-dom";
// 修改为
import ReactDOM from 'react-dom/client';
  • 修改SpeechText组件渲染逻辑:
// 原代码
ReactDOM.render(
  <SpeechText />,
  document.getElementById("custom-foot-bar")
);
// 修改为
const root = ReactDOM.createRoot(document.getElementById("custom-foot-bar"));
root.render(<SpeechText />);

2. DOM检查与状态更新逻辑错误

你在会议成功回调里,先启动定时器更新ele状态,紧接着就判断ele长度——此时ele还是初始空值,定时器回调尚未执行,导致渲染逻辑无法触发,还可能引发内存泄漏。
修复步骤:

  • 删除const [ele, setEle] = useState(...)这段状态代码
  • 直接在定时器内完成DOM检查与组件渲染:
var refreshInterval = setInterval(() => {
  const footerContainer = document.getElementsByClassName("footer__btns-container")[0];
  if (footerContainer) {
    const createdEle = document.createElement("div");
    createdEle.setAttribute("id", "custom-foot-bar");
    footerContainer.appendChild(createdEle);
    const root = ReactDOM.createRoot(createdEle);
    root.render(<SpeechText />);
    clearInterval(refreshInterval);
  }
}, 2000);

3. JWT签名环境变量不统一

你在JWT payload里混用了process.env.REACT_SDK_KEY和process.env.REACT_APP_SDK_KEY,React项目环境变量必须以REACT_APP_开头才能被正确注入。
修复步骤:统一使用正确的环境变量名:

const oPayload = {
  sdkKey: process.env.REACT_APP_SDK_KEY,
  mn: meetNo,
  role: role,
  iat: iat,
  exp: exp,
  appKey: process.env.REACT_APP_SDK_KEY,
  tokenExp: iat + 60 * 60 * 2,
};
// 以及签名部分
const signature = KJUR.jws.JWS.sign(
  "HS256",
  sHeader,
  sPayload,
  process.env.REACT_APP_SDK_KEY
);

4. URL验证正则表达式错误

原正则里zoom\us多了一个转义符,导致无法匹配合法Zoom链接,修改为:

!meetURL.match(/^https:\/\/us05web\.zoom\.us\/j\/\d+\?pwd=[a-zA-Z0-9]+$/)

5. 变量声明规范问题

建议将所有var声明改为let或const,避免作用域污染问题。

内容的提问来源于stack exchange,提问作者Nikhil Kumar Sahu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 07:16:23