首页 > web前端 > js教程 > 正文

在 React 中构建实时通知中心

PHPz
发布: 2024-08-24 11:14:02
原创
506 人浏览过

Building a Real-Time Notification Center in React

通知让用户了解情况并参与其中。自定义 React 通知中心可让您完全控制和定制用户体验。这是从头开始构建一个简明指南,涵盖用于实时更新的前端和后端组件。

1. React 通知中心的要求

  • 实时更新:通知应立即显示,无需刷新。
  • 后台通知:即使应用程序未处于焦点状态,也可以使用 Service Worker 来处理通知。
  • 多渠道支持:包括应用内通知、推送通知、电子邮件和短信。
  • 用户首选项:允许用户自定义其通知设置。
  • 可扩展性:确保系统可以处理大量通知。
  • 可靠性:通知必须准确、及时地发送。

2. 系统架构概述

前端

  • React App:显示通知并处理实时更新。
  • Service Worker:通过通知 API 管理后台通知。
  • WebSocket/轮询:保持通知源实时更新。

后端

  • 微服务
    • 通知服务:生成并存储通知。
    • 调度服务:向各个渠道发送通知。
    • 用户首选项服务:管理通知的用户设置。
  • 消息队列:高效处理通知分发。
  • 数据库:存储用户首选项和通知日志。
  • 推送服务:与 Firebase 和 APN 集成以发送通知。

3. 后端架构

3.1.微服务设计

微服务 功能 标题>
Microservice Functionality
Notification Service Generates and stores notifications
Dispatch Service Sends notifications to different channels
User Preferences Service Manages user settings and preferences
通知服务 生成并存储通知 派遣服务 向不同渠道发送通知 用户偏好服务 管理用户设置和首选项 表>

3.2.数据库设计

  • 通知表:存储通知元数据。
  • 用户首选项表:跟踪用户设置。
  • 日志表:记录所有发送的通知。

示例:Node.js/Express 中的通知服务

const express = require('express');
const app = express();

let notifications = [];

app.post('/notify', (req, res) => {
    const notification = {
        id: notifications.length + 1,
        type: req.body.type,
        message: req.body.message,
        userId: req.body.userId,
        status: 'unread',
        timestamp: new Date()
    };

    notifications.push(notification);
    res.status(200).send(notification);
});

app.listen(3000, () => {
    console.log('Notification Service running on port 3000');
});
登录后复制

4. 实时沟通

4.1. WebSocket 连接

  • 服务器:处理连接并广播通知。
  • 客户端:监听更新并实时更新UI。

示例:带有 Socket.IO 的 WebSocket 服务器

const io = require('socket.io')(3001);

io.on('connection', (socket) => {
    console.log('User connected:', socket.id);

    socket.emit('notification', {
        message: 'New notification!',
        timestamp: new Date()
    });

    socket.on('disconnect', () => {
        console.log('User disconnected:', socket.id);
    });
});
登录后复制

React 中的客户端集成

import React, { useEffect, useState } from 'react';
import io from 'socket.io-client';

const socket = io('http://localhost:3001');

function NotificationCenter() {
    const [notifications, setNotifications] = useState([]);

    useEffect(() => {
        socket.on('notification', (notification) => {
            setNotifications(prev => [...prev, notification]);
        });
    }, []);

    return (
        <div>
            <h2>Notification Center</h2>
            {notifications.map((notif, index) => (
                <div key={index}>{notif.message} - {notif.timestamp}</div>
            ))}
        </div>
    );
}

export default NotificationCenter;
登录后复制

4.2.轮询作为后备

  • 客户端:定期检查服务器是否有新通知。

示例:React 中的轮询实现

import React, { useEffect, useState } from 'react';

function NotificationCenter() {
    const [notifications, setNotifications] = useState([]);

    useEffect(() => {
        const interval = setInterval(() => {
            fetch('/api/notifications')
                .then(response => response.json())
                .then(data => setNotifications(data));
        }, 5000); // Poll every 5 seconds

        return () => clearInterval(interval);
    }, []);

    return (
        <div>
            <h2>Notification Center</h2>
            {notifications.map((notif, index) => (
                <div key={index}>{notif.message}</div>
            ))}
        </div>
    );
}

export default NotificationCenter;
登录后复制

5. 集成通知 API 和 Service Worker

5.1.服务人员

  • 注册:处理后台通知。

示例:注册 Service Worker

if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/sw.js').then(registration => {
        console.log('Service Worker registered:', registration.scope);
    }).catch(error => {
        console.error('Service Worker registration failed:', error);
    });
}
登录后复制

5.2.通知API

  • 权限处理:请求显示通知的权限。
  • 触发通知:即使应用程序未处于活动状态也显示通知。

示例:显示通知

if (Notification.permission === 'granted') {
    new Notification('New message!', {
        body: 'Click to view the message.',
        icon: '/path/to/icon.png'
    });
} else if (Notification.permission !== 'denied') {
    Notification.requestPermission().then(permission => {
        if (permission === 'granted') {
            new Notification('New message!', {
                body: 'Click to view the message.',
                icon: '/path/to/icon.png'
            });
        }
    });
}
登录后复制

6. 使用 Firebase 和 APN 推送通知

6.1. Firebase 云消息传递 (FCM)

  • 设置:注册 Firebase 并获取令牌。
  • 发送通知:使用令牌发送通知。

示例:在 Node.js 中使用 FCM 发送推送通知

const admin = require('firebase-admin');
const serviceAccount = require('./path/to/serviceAccountKey.json');

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount)
});

const message = {
    notification: {
        title: 'New Notification',
        body: 'You have a new notification!'
    },
    token: 'device-token'
};

admin.messaging().send(message)
    .then(response => console.log('Message sent:', response))
    .catch(error => console.error('Error sending message:', error));
登录后复制

6.2. Apple 推送通知服务 (APN)

  • 集成:处理设备令牌并使用它们通过 APN 发送通知。

7. 在 React 中构建通知中心 UI

7.1.设计通知源

  • 通知列表:显示所有通知,并带有标记为已读或删除的选项。
  • 通知徽章:显示未读通知数量。
  • Toast 通知:使用像 React-toastify 这样的库来获取简短通知。

示例:通知列表组件

import React from 'react';

function NotificationList({ notifications }) {
    return (
        <div>
            {notifications.map(notification => (
                <div key={notification.id}>{notification.message}</div>
            ))}
        </div>
    );
}

export default NotificationList;
登录后复制

示例:使用 React-toastify 的 Toast 通知

import { toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

toast.configure();

function notify() {
    toast('New notification!', { position: toast.POSITION.BOTTOM_RIGHT });
}

notify();
登录后复制

7.2.使用 Redux 或 Context API 管理状态

  • 全局商店:使用 Redux 或 Context API 全局管理通知。
  • 实时更新:通过 WebSocket 或轮询使用新通知更新商店。

示例:使用 Redux 管理状态

import { createSlice } from '@reduxjs/toolkit';

const notificationSlice = createSlice({
    name: 'notifications',
    initialState: [],
    reducers: {
        addNotification: (state, action) => {
            state.push(action.payload);
        },
        markAsRead: (state, action) => {
            const notification = state.find(n => n.id === action.payload);
            if (notification) {
                notification.read = true;
            }
        }
    }
});

export const { addNotification, markAsRead } = notificationSlice.actions;
export default notificationSlice.reducer;
登录后复制

作为一名优秀的开发人员,您应该继续从头开始构建 React 通知系统,但是,如果您的老板尽快需要它并且您已经计划了假期(或者只是真的需要休息),请查看我的工具。它简化了一切,并为您提供了即用型组件作为新的通知 API,可在所有流行的 SDK 中使用。所以您可以在我们处理基础设施时放松一下! ??

以上是在 React 中构建实时通知中心的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!