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

React应用中SignalR无法获取数据当前状态的原因排查

问题原因

这是典型的React闭包陷阱:组件首次渲染时,addData函数被传递给SignalR服务,它捕获了当时的data状态(空数组)。后续loadData获取到数据更新data后,组件重新渲染会生成新的addData函数,但SignalR绑定的还是最初那个旧的addData,所以它始终读取的是初始的空data。

解决方案:使用函数式更新修改状态

不需要额外冗余状态,直接修改addData函数,利用React的setState函数式更新特性——它会接收当前最新的状态值作为参数,完全避开闭包问题:

function addData(addedItem: DataModel) {
    // prevData是React传入的当前最新状态
    setData(prevData => [...prevData, addedItem]);
}
额外优化:避免内存泄漏

当前代码的useEffect没有清理SignalR的事件监听,组件卸载后可能还会收到回调,引发内存泄漏。可以给useEffect加上清理逻辑:

useEffect(() => {
    loadSignalR();
    loadData();

    // 组件卸载时移除SignalR的事件监听
    return () => {
        if (signalRService.connection) {
            signalRService.connection.off('DataAdded');
        }
    };
}, []);

进一步优化SignalR服务,让onDataAdded返回清理函数,避免重复绑定:

// 修改signalRService的onDataAdded方法
onDataAdded: callback => {
    const handler = serverData => callback(serverData);
    signalRService.connection.on('DataAdded', handler);
    // 返回移除监听的函数
    return () => signalRService.connection.off('DataAdded', handler);
}

// 组件中使用
useEffect(() => {
    loadData();
    signalRService.startConnection(`${BASE_PATH}/dataHub`);
    const removeListener = signalRService.onDataAdded(addData);

    return () => {
        removeListener();
        // 可选:如需断开连接可在此处理
        // signalRService.connection?.stop();
    };
}, []);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 18:22:34