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

React中Socket接收数据时useState值未更新的问题

问题原因及解决方案

这是典型的React闭包陷阱:你的useEffect依赖数组只声明了socket,所以组件第一次渲染时生成的spin函数会一直捕获初始状态的counter值(也就是0)。哪怕之后你通过setCounter把counter改成2,socket绑定的还是第一次渲染时的旧spin函数,所以触发事件时只会打印初始的0。

下面给两种可行的解决办法:

方法1:将counter加入依赖数组,同步更新事件监听

每次counter变化时,重新创建spin函数并绑定,同时清理旧的监听避免重复触发:

const [counter, setCounter] = useState(0)

useEffect(() => {
  if (socket == null) return
  
  const spin = (dat) => {
    if (dat !== '') {
      console.log(counter)
    }
  }
  
  socket.on("receive-spin", spin)
  
  // 组件卸载或依赖变化时,移除旧的事件监听
  return () => {
    socket.off("receive-spin", spin)
  }
}, [socket, counter]) // 把counter加入依赖数组

方法2:用useRef保存counter的最新值(适合counter频繁更新的场景)

通过useRef存储counter的最新状态,让spin函数总能访问到最新值,无需频繁解绑绑定事件:

const [counter, setCounter] = useState(0)
const counterRef = useRef(counter)

// 同步counter状态到ref
useEffect(() => {
  counterRef.current = counter
}, [counter])

useEffect(() => {
  if (socket == null) return
  
  const spin = (dat) => {
    if (dat !== '') {
      console.log(counterRef.current) // 直接取ref的current,永远是最新值
    }
  }
  
  socket.on("receive-spin", spin)
  
  return () => {
    socket.off("receive-spin", spin)
  }
}, [socket])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 22:54:55