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

WebRTC会议室异步函数重复调用时React状态更新异常如何解决?

问题原因与解决方案

问题根源

你碰到的是React useState的闭包陷阱:

  • 当WebSocket收到多条createOffer消息时,pc.getMedia().then是异步操作,回调里的connectionList是捕获的旧状态快照。
  • 两次更新都基于同一个旧数组(比如初始空数组)执行[...connectionList, newItem],导致后一次更新覆盖前一次,最终只保留一个用户。

解决方法

使用useState的函数式更新,React会自动传入最新的state作为参数,确保每次更新都基于当前最新的状态:

修改两处setConnectionList的写法:

const [connectionList, setConnectionList] = useState([]);

webSocket.current.onmessage = function (e) {

  let msgDispatcher = JSON.parse(e.data);
  console.log("msgDispatcher", msgDispatcher);

  if (msgDispatcher.pcCommand == "broadcast") {
    console.log("prepare Connection");

    let pc = new PeerConnection();
    pc.getMedia();
    // 改成函数式更新
    setConnectionList(prevList => [...prevList, {
      fromUserID: msgDispatcher.fromUserID,
      connection: pc,
      id: uuid()
    }]);

    webSocket.current.send(JSON.stringify({
      sendType: "toUser",
      toUserID: msgDispatcher.fromUserID,
      fromUserID: userID,
      pcCommand: "createOffer"
    }));

  }

  if (msgDispatcher.pcCommand == "createOffer") {
    console.log("createOffer");
    let pc = new PeerConnection();

    pc.getMedia().then((e) => {
  
      pc.createOffer(webSocket.current, userID, msgDispatcher.fromUserID);
      
      // 改成函数式更新
      setConnectionList(prevList => [...prevList, {
        fromUserID: msgDispatcher.fromUserID,
        connection: pc,
        id: uuid()
      }])
    })
}

原理说明

函数式更新的prevList是React提供的当前最新状态,每次调用都会基于这个最新数组添加新元素,不管是同步还是异步触发的更新,都能正确累积状态,不会出现覆盖问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 18:23:07