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

