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
相关产品推荐
相关产品推荐

