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

如何检测数组是否新增值?实现自定义未读通知计数器

自定义未读通知计数器实现方案

核心逻辑

用useRef存储上一次拉取到的通知列表长度,每次获取新数据时对比新旧长度,把长度差加到未读计数器里——这正好匹配你想要的“根据数组前后长度差异更新计数器”的思路。

具体代码实现

首先需要新增两个关键变量:

  • unreadCount状态:用来存最终显示的未读数量
  • prevLengthRef引用:保存上一次的通知列表长度,避免状态更新带来的重渲染干扰

然后修改你的请求逻辑,完整代码如下:

import { useState, useEffect, useRef } from 'react';
import axios from 'axios';

const YourComponent = () => {
  const [notificationList, setNotificationList] = useState([]);
  const [unreadCount, setUnreadCount] = useState(0);
  // 存储上一次的通知列表长度
  const prevLengthRef = useRef(0);

  useEffect(() => {
    const getNotifications = async () => {
      try {
        const res = await axios.get(USER_API);
        const newList = res.data.data;
        const newLength = newList.length;
        const oldLength = prevLengthRef.current;

        // 只有新列表长度大于旧长度时,将差值累加到计数器
        if (newLength > oldLength) {
          setUnreadCount(prev => prev + (newLength - oldLength));
        }

        setNotificationList(newList);
        // 更新引用为最新的列表长度
        prevLengthRef.current = newLength;
      } catch (err) {
        console.log('error from getNotifications', err);
      }
    };

    // 首次加载拉取通知
    getNotifications();
    // 可选:定时轮询拉取新通知,示例为每30秒一次
    const interval = setInterval(getNotifications, 30000);
    return () => clearInterval(interval);
  }, []);

  // 用户查看通知后重置计数器的方法
  const resetUnreadCount = () => {
    setUnreadCount(0);
    // 此处可添加调用后端接口标记所有通知为已读的逻辑
  };

  return (
    <div>
      {/* 未读计数器展示 */}
      <div className="notification-badge">
        {unreadCount > 0 && <span>{unreadCount}</span>}
      </div>
      <button onClick={resetUnreadCount}>标记全部已读</button>
      {/* 通知列表渲染 */}
      <ul>
        {notificationList.map(item => (
          <li key={item.id}>{item.content}</li>
        ))}
      </ul>
    </div>
  );
};

export default YourComponent;

额外优化建议

如果后端返回的通知数据带有isRead这类已读状态字段,建议优先基于该字段计算未读数量——这种方式比单纯对比列表长度更准确,能避免因通知删除导致的长度差误判:

// 替换原有的长度对比逻辑
const actualUnread = newList.filter(notice => !notice.isRead).length;
setUnreadCount(actualUnread);

另外,定时轮询的间隔可根据业务需求调整,也可以结合WebSocket实现实时推送,减少不必要的重复请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 13:45:29