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

React中SignalR消息处理函数无法获取最新组件状态问题

React + SignalR 回调无法获取最新组件状态的问题解决

这是闭包陷阱导致的问题:你的connect函数在组件首次挂载时(useEffect空依赖)执行,此时connection.on注册的ReceiveMyMessage回调捕获了当时的counter初始值(0)。后续counter更新触发组件重渲染时,这个回调函数仍引用着第一次渲染时的闭包,所以始终打印旧值。

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

useRef的.current属性是可变的,不会触发组件重渲染,且能在闭包中始终拿到最新值,是解决这类问题的最优方案。

修改后的代码示例:

import { useState, useEffect, useRef } from 'react';
import { HubConnectionBuilder, LogLevel, HubConnection } from '@microsoft/signalr';

const YourComponent = () => {
  const [counter, setCounter] = useState(0);
  const [connection, setConnection] = useState<HubConnection>();
  // 用useRef保存最新的counter值
  const counterRef = useRef(counter);

  // 每次counter更新时同步到ref
  useEffect(() => {
    counterRef.current = counter;
  }, [counter]);

  const MyLog = (message: string) => {
    console.log(message);
    // 访问ref的current属性获取最新值
    console.log(counterRef.current);
  };

  useEffect(() => {
    const connect = async (): Promise<void> => {
      const connectionInstance = new HubConnectionBuilder()
        .withUrl(import.meta.env.VITE_SIGNALR)
        .configureLogging(LogLevel.Information)
        .build();

      connectionInstance.on("ReceiveMyMessage", (message) => {
        MyLog(message);
      });

      await connectionInstance.start();
      setConnection(connectionInstance);
    };

    connect();

    // 组件卸载时关闭连接,避免内存泄漏
    return async () => {
      if (connection) {
        await connection.stop();
      }
    };
  }, []);

  // 递增counter的按钮事件
  const incrementCounter = () => {
    setCounter(prev => prev + 1);
  };

  return (
    <div>
      <p>当前计数:{counter}</p>
      <button onClick={incrementCounter}>计数+1</button>
    </div>
  );
};

export default YourComponent;

原理说明

  • counterRef.current会在counter状态更新时同步最新值,不受闭包的限制。
  • SignalR的回调函数中访问counterRef.current,每次触发时都能拿到组件的最新状态值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 12:05:01