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

React+Next.js实现Sendbird Chat未读消息频道数实时更新求助

实现Sendbird未读频道总数实时更新的自定义Hook(React/Next.js)

核心思路

无需调用平台API轮询,依赖Sendbird Chat SDK的实时事件推送和本地状态维护,即可实时同步未读频道数量,减少服务器请求开销。


方法一:基于Sendbird SDK事件监听的自定义Hook

利用SDK提供的频道更新、消息接收、标记已读等事件,实时更新未读频道计数。

完整Hook代码

import { useEffect, useState } from 'react';
import SendbirdChat from '@sendbird/chat';
import { GroupChannel } from '@sendbird/chat/groupChannel';

export const useUnreadChannelCount = () => {
  const [unreadChannelCount, setUnreadChannelCount] = useState(0);

  useEffect(() => {
    const sbInstance = SendbirdChat.getCurrentInstance();
    if (!sbInstance) return;

    // 初始化:获取当前未读频道总数
    const fetchInitialUnreadCount = async () => {
      const unreadChannels = await sbInstance.groupChannel.getMyGroupChannels({
        includeEmpty: false,
        includeFrozen: false,
        unreadFilter: 'unread',
      });
      setUnreadChannelCount(unreadChannels.length);
    };
    fetchInitialUnreadCount();

    // 频道更新时重新统计未读数量
    const handleChannelUpdated = async () => {
      const unreadChannels = await sbInstance.groupChannel.getMyGroupChannels({
        includeEmpty: false,
        includeFrozen: false,
        unreadFilter: 'unread',
      });
      setUnreadChannelCount(unreadChannels.length);
    };

    // 收到新消息时,若频道未读则计数+1
    const handleMessageReceived = (channel: GroupChannel) => {
      if (!channel.isRead) {
        setUnreadChannelCount(prev => prev + 1);
      }
    };

    // 标记频道为已读时,计数-1
    const handleChannelMarkedAsRead = () => {
      setUnreadChannelCount(prev => Math.max(prev - 1, 0));
    };

    // 注册事件监听器
    const handlerId = 'unread-channel-count-handler';
    sbInstance.groupChannel.addGroupChannelHandler(handlerId, {
      onChannelUpdated: handleChannelUpdated,
      onMessageReceived: handleMessageReceived,
      onChannelMarkAsRead: handleChannelMarkedAsRead,
    });

    // 组件卸载时清理监听器
    return () => {
      sbInstance.groupChannel.removeGroupChannelHandler(handlerId);
    };
  }, []);

  return unreadChannelCount;
};

使用方式

在任意组件中直接调用该Hook,即可获取实时更新的未读频道数:

import { useUnreadChannelCount } from './hooks/useUnreadChannelCount';

export const Header = () => {
  const unreadCount = useUnreadChannelCount();
  return <div className="header-badge">{unreadCount}</div>;
};

方法二:结合UIKit <ChannelList> 组件统计

若使用Sendbird UIKit的<ChannelList>,可通过组件内置事件和自定义渲染逻辑统计未读频道数。

示例代码

import { useState } from 'react';
import { ChannelList } from '@sendbird/uikit-react/ChannelList';

export const ChannelListWithUnreadCounter = () => {
  const [unreadChannelCount, setUnreadChannelCount] = useState(0);

  return (
    <div>
      <div className="unread-counter">未读频道:{unreadChannelCount}</div>
      <ChannelList
        // 频道列表更新时重新统计未读数量
        onChannelListUpdated={(channels) => {
          const count = channels.filter(channel => channel.isUnread).length;
          setUnreadChannelCount(count);
        }}
        // 自定义频道项渲染(可选)
        renderChannel={(channel) => (
          <div className="channel-item">
            <h3>{channel.name}</h3>
            {channel.unreadMessageCount > 0 && (
              <span className="message-badge">{channel.unreadMessageCount}</span>
            )}
          </div>
        )}
      />
    </div>
  );
};

关键说明

  • onChannelListUpdated事件会在频道列表发生变化(如新增频道、未读状态改变)时触发,此时过滤出isUnread为true的频道即可得到总数。
  • 无需额外调用API,完全依赖UIKit内部的状态同步。

注意事项

  1. 确保Sendbird SDK已完成初始化,且用户处于登录状态。
  2. 事件监听器必须在组件卸载时清理,避免内存泄漏。
  3. 若未读频道数量极大,可考虑优化getMyGroupChannels的查询参数(如添加分页),但一般场景下无需处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:27:25