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

React中Stomp订阅回调内myState为空的问题求助

问题原因与解决方案

这是React的闭包陷阱导致的:你的onMessageReceiveEvent函数在组件渲染时创建,会捕获当前渲染周期的myState值。而你的useEffect仅在d1或d2变化时重新执行、创建新的订阅和回调。后续组件因myState更新重新渲染时,旧订阅的回调依然引用初始的空数组myState,所以打印结果为空。

解决方案1:用useRef保存最新状态引用

通过useRef存储最新的myState,它的.current属性可变且不会被闭包锁定,每次状态更新时同步更新ref:

const [myState, setState] = useState([/* 初始数组值 */]);
const myStateRef = useRef(myState);

// 同步状态到ref,确保ref始终指向最新值
useEffect(() => {
  myStateRef.current = myState;
}, [myState]);

const onMessageReceiveEvent = (res) => {
  console.log(myStateRef.current); // 此处可获取最新状态
};

// 原useEffect逻辑保持不变
useEffect(() => {
  if (d1 && d2) {
    const socket = new SockJS(WS_URL, {}, {CheckOrigin: () => false});
    stompClient = Stomp.over(socket);
    stompClient.connect({}, () => {
      stompClient?.subscribe(`/topic/chat/${d1.id}`, onMessageReceiveEvent);
      stompClient?.subscribe(`/topic/chat/status/${d1.id}`, onCurrentReplyEvent);
    });      
  }
  return () => {
    stompClient?.disconnect();
  }
},[d1,d2]);

解决方案2:用函数式更新获取最新状态(若目标是更新状态)

如果你的需求是在回调里更新myState,直接使用函数式更新即可,React会自动传入最新的状态值,无需依赖当前myState:

const onMessageReceiveEvent = (res) => {
  // 示例:添加新数据到状态数组
  setState(prevState => {
    console.log(prevState); // 此处为最新状态
    return [...prevState, 新数据];
  });
};

解决方案3:让回调依赖最新状态(配合useCallback与重新订阅)

用useCallback包裹回调函数,将其加入useEffect的依赖列表,这样每次myState变化时,useEffect会重新执行并创建新订阅(注意先取消旧订阅):

const onMessageReceiveEvent = useCallback((res) => {
  console.log(myState);
}, [myState]);

useEffect(() => {
  if (!d1 || !d2) return;
  
  const socket = new SockJS(WS_URL, {}, {CheckOrigin: () => false});
  const client = Stomp.over(socket);
  let subscription1, subscription2;

  client.connect({}, () => {
    subscription1 = client.subscribe(`/topic/chat/${d1.id}`, onMessageReceiveEvent);
    subscription2 = client.subscribe(`/topic/chat/status/${d1.id}`, onCurrentReplyEvent);
  });

  return () => {
    // 清理旧订阅
    subscription1?.unsubscribe();
    subscription2?.unsubscribe();
    client.disconnect();
  }
},[d1,d2, onMessageReceiveEvent]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 16:35:14