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

React useEffect中WebSocket onmessage无法获取更新后的State值求助

React中WebSocket回调无法获取最新State值的解决方案

问题原因

你的useEffect依赖数组为空,只会在组件首次挂载时执行一次。此时onmessage回调通过闭包捕获了初始的max值(10),后续调用setMax更新state时,组件会重新渲染,但因为useEffect没监听max的变化,不会重新生成回调,所以回调里始终用的是最初的旧值。

解决方案一:将max加入useEffect依赖数组

每次max更新时,重新绑定onmessage回调,确保回调能拿到最新的max值:

const [max, setMax] = useState<number>(10);

useEffect(() => {
     console.log('max', max);

     // 每次max更新时重新绑定回调,覆盖旧回调
     ws.onmessage = (message: MessageEvent) => {
          console.log('max', max);

          if (max > 100) {
                doSomething(message.data); // 注意:消息内容在message.data中
          }
     }

     // 组件卸载时清理回调,避免内存泄漏
     return () => {
          ws.onmessage = null;
     }
}, [max]); // 把max加入依赖数组,触发回调重新绑定

function onChange() {
      setMax(1000);
}

<Select onChange={onChange}></Select>

解决方案二:用useRef保存最新State值

如果不想每次max更新都重新绑定回调,可以用useRef存储最新值,它的.current属性不受闭包限制,始终能拿到最新数据:

const [max, setMax] = useState<number>(10);
const maxRef = useRef<number>(max);

// 同步state到ref,确保ref始终是最新值
useEffect(() => {
     maxRef.current = max;
}, [max]);

useEffect(() => {
     console.log('max', max);

     ws.onmessage = (message: MessageEvent) => {
          // 从ref中获取最新的max值
          const currentMax = maxRef.current;
          console.log('max', currentMax);

          if (currentMax > 100) {
                doSomething(message.data);
          }
     }

     return () => {
          ws.onmessage = null;
     }
}, []); // 依赖为空,只绑定一次回调

function onChange() {
      setMax(1000);
}

<Select onChange={onChange}></Select>

方案选择

  • 如果max更新频率不高,方案一简单直接,容易维护;
  • 如果max频繁更新,方案二更高效,避免重复绑定回调的开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 03:05:32