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

React集成SignalR最佳实践:封装SignalR为自定义Hook方案

解决方案:将SignalR逻辑封装到自定义Hook

自定义Hook实现

我们可以创建独立的useSignalRImageData Hook,把数据获取、SignalR连接管理、通知响应逻辑全部封装进去,让组件只专注于UI渲染。

import { useReducer, useEffect, useCallback } from "react";
import { cardDataReducer, initialCapturedImages } from "../../reducers/reducer";
import { GetImages } from "../../services/mongo";
import { setUpListener } from "../../services/signalR";

export function useSignalRImageData(limit = 10) {
  const [cardData, dispatch] = useReducer(cardDataReducer, initialCapturedImages);

  // 封装数据获取逻辑,用useCallback避免重复创建函数
  const fetchData = useCallback(async () => {
    try {
      const data = await GetImages(limit);
      dispatch({
        type: 'fetched',
        capturedImageFetch: data,
        id: "",
        text: "",
        capturedImage: undefined
      });
    } catch (err) {
      console.error("获取图片失败:", err);
    }
  }, [limit]);

  useEffect(() => {
    // 初始化加载数据
    fetchData();

    // 建立SignalR监听,收到通知时触发数据刷新
    const signalRConnection = setUpListener(() => {
      fetchData();
    });

    // 组件卸载时清理SignalR连接,避免内存泄漏
    return () => {
      // 根据你的setUpListener返回的连接对象调整清理逻辑,比如调用stop方法
      if (signalRConnection?.stop) {
        signalRConnection.stop();
      }
    };
  }, [fetchData]);

  return cardData;
}

Hook逻辑说明

  • 状态复用:保留原有的useReducer状态管理逻辑,保证状态一致性
  • 初始化加载:组件挂载时自动执行一次数据获取
  • SignalR管理:在同一个useEffect中创建监听,仅收到服务器通知时触发数据刷新
  • 自动清理:组件卸载时断开SignalR连接,防止无效连接残留
  • 性能优化:用useCallback包裹fetchData,避免因函数引用变化导致的重复执行

重构原组件

简化BaseMediaLayout组件,直接使用自定义Hook获取数据,组件仅负责UI渲染:

import * as React from "react";
import Grid from '@mui/material/Unstable_Grid2'; // Grid version 2
import { Container } from "@mui/material";
import { useSignalRImageData } from "./useSignalRImageData"; // 调整Hook导入路径

export function BaseMediaLayout() {
  const cardData = useSignalRImageData(10);

  return (
    <Container>
      <Grid>
        {/* 这里渲染你的图片卡片,例如:cardData.items.map(item => ...) */}
      </Grid>
    </Container>
  );
}

解决的核心问题

  • 消除重复API调用:仅在初始化和收到SignalR通知时调用GetImages,避免原代码中依赖lastUpdated导致的不必要重复请求
  • 逻辑解耦:SignalR和数据获取逻辑从组件中剥离,组件更简洁,维护性更强
  • 避免连接泄漏:自动处理SignalR连接的创建与销毁,防止组件重复渲染时创建多个连接
  • 提升可复用性:自定义Hook可以在其他需要监听图片更新的组件中直接复用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 11:22:06