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

如何在MERN网站实现单通道通知及通知铃铛动态计数器

MERN栈实现通知铃铛未读计数器及清零功能

1. 后端(Node.js + Express + MongoDB)

数据模型调整

给通知模型新增isRead字段(默认未读),同时关联用户ID,确保每个用户的通知独立统计:

// models/Notification.js
const mongoose = require('mongoose');

const notificationSchema = new mongoose.Schema({
  content: { type: String, required: true },
  userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
  isRead: { type: Boolean, default: false },
  createdAt: { type: Date, default: Date.now }
});

module.exports = mongoose.model('Notification', notificationSchema);

核心接口实现

  • 获取未读通知数量:查询当前用户的未读通知总数
// routes/notifications.js
router.get('/unread-count', async (req, res) => {
  try {
    // 假设已通过JWT中间件获取当前用户ID并存入req.user
    const unreadCount = await Notification.countDocuments({
      userId: req.user._id,
      isRead: false
    });
    res.json({ count: unreadCount });
  } catch (err) {
    res.status(500).json({ message: '获取未读数量失败' });
  }
});
  • 标记所有通知为已读:点击铃铛时调用,批量更新当前用户的未读状态
router.put('/mark-all-read', async (req, res) => {
  try {
    await Notification.updateMany(
      { userId: req.user._id, isRead: false },
      { $set: { isRead: true } }
    );
    res.json({ message: '所有通知已标记为已读' });
  } catch (err) {
    res.status(500).json({ message: '标记已读失败' });
  }
});

2. 前端(React)

状态管理与交互逻辑

用React内置状态管理计数器,结合接口实现数据同步:

import { useState, useEffect } from 'react';

function NotificationBell() {
  const [unreadCount, setUnreadCount] = useState(0);
  const token = localStorage.getItem('authToken');

  // 初始化+定时刷新未读数量
  useEffect(() => {
    fetchUnreadCount();
    // 30秒轮询一次,可根据需求调整频率
    const interval = setInterval(fetchUnreadCount, 30000);
    return () => clearInterval(interval);
  }, []);

  // 请求未读数量
  const fetchUnreadCount = async () => {
    try {
      const res = await fetch('/api/notifications/unread-count', {
        headers: { Authorization: `Bearer ${token}` }
      });
      const data = await res.json();
      setUnreadCount(data.count);
    } catch (err) {
      console.error('获取未读数量出错:', err);
    }
  };

  // 点击铃铛触发标记已读+清零计数器
  const handleBellClick = async () => {
    try {
      await fetch('/api/notifications/mark-all-read', {
        method: 'PUT',
        headers: { Authorization: `Bearer ${token}` }
      });
      setUnreadCount(0);
      // 此处可同步更新通知列表的已读状态
    } catch (err) {
      console.error('标记已读出错:', err);
    }
  };

  return (
    <div onClick={handleBellClick} style={{ cursor: 'pointer', position: 'relative' }}>
      {/* 替换为你的铃铛图标 */}
      <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
        <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/>
        <path d="M13.73 21a2 2 0 0 1-3.46 0"/>
      </svg>
      {/* 未读数量标记,仅当数量>0时显示 */}
      {unreadCount > 0 && (
        <span style={{
          position: 'absolute',
          top: '-4px',
          right: '-4px',
          backgroundColor: '#ff4444',
          color: 'white',
          borderRadius: '50%',
          width: '20px',
          height: '20px',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          fontSize: '12px',
          fontWeight: 'bold'
        }}>
          {unreadCount}
        </span>
      )}
    </div>
  );
}

export default NotificationBell;

实时更新优化(可选)

如果需要管理员发布通知后用户立即收到提醒,可替换轮询为Socket.io:

  • 后端安装socket.io,在发布通知时向目标用户推送事件:
// 管理员发布通知的接口中
const newNotification = await Notification.create({
  content: req.body.content,
  userId: req.body.targetUserId
});
// 向目标用户的专属房间推送事件
io.to(`user-${req.body.targetUserId}`).emit('new-notification');
  • 前端连接Socket.io,收到事件后刷新计数器:
import { io } from 'socket.io-client';

// 在组件的useEffect中添加
useEffect(() => {
  const socket = io();
  // 加入当前用户的专属房间
  socket.emit('join-room', `user-${currentUserId}`);
  // 收到新通知时刷新数量
  socket.on('new-notification', fetchUnreadCount);
  return () => socket.disconnect();
}, [currentUserId]);

关键注意事项

  • 确保用户认证逻辑正确,接口能通过req.user获取当前用户ID
  • 多用户场景下,严格通过userId过滤通知,避免数据混淆
  • 计数器样式可根据项目UI规范调整,上述为基础示例

内容的提问来源于stack exchange,提问作者Md Hridoy Ahmmed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 22:36:19