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

React前端开发者求助:如何实现API实时通知数据获取

Hey there! I get where you're coming from—socket.io tutorials do lean heavily into chat apps, but it's absolutely capable of handling real-time notifications for your React project without a full rewrite. Let's walk through practical solutions that fit your existing setup.

Option 1: Socket.io (Flexible for Bidirectional Communication)

Socket.io isn't limited to chat—it’s a general-purpose real-time communication tool. Since your backend is already complete, you just need to add socket.io support to it (most backend languages have socket.io implementations, not just Node.js) and integrate the client into your React app.

Step 1: Frontend Integration (React)

First, install the socket.io client:
npm install socket.io-client

Then, here’s a reusable notification component that connects to your socket server, authenticates with your existing token, and listens for real-time updates:

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

const RealTimeNotifications = () => {
  const [notifications, setNotifications] = useState([]);
  const [socket, setSocket] = useState(null);

  useEffect(() => {
    // Initialize socket connection with your auth token
    const userToken = localStorage.getItem('authToken'); // Or pull from your state management
    const newSocket = io('https://your-backend-url.com', {
      auth: { token: userToken }
    });

    // Handle successful connection
    newSocket.on('connect', () => {
      console.log('Connected to real-time server');
    });

    // Listen for new notifications from the backend
    newSocket.on('new-notification', (freshNotification) => {
      setNotifications(prev => [freshNotification, ...prev]);
    });

    // Handle connection errors
    newSocket.on('connect_error', (err) => {
      console.error('Socket connection failed:', err.message);
    });

    setSocket(newSocket);

    // Clean up on component unmount
    return () => newSocket.close();
  }, []);

  return (
    <div className="notifications-container">
      <h3>Real-Time Notifications</h3>
      {notifications.length === 0 ? (
        <p>No new notifications</p>
      ) : (
        notifications.map(notification => (
          <div key={notification.id} className="notification-item">
            <p>{notification.message}</p>
            <small>{new Date(notification.timestamp).toLocaleString()}</small>
          </div>
        ))
      )}
    </div>
  );
};

export default RealTimeNotifications;

Step 2: Backend Setup (Example with Node.js/Express)

If your backend uses Node.js, here’s how to add socket.io with token validation (match your existing auth logic):

const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const jwt = require('jsonwebtoken'); // Use your existing auth library

const app = express();
const server = http.createServer(app);
const io = new Server(server, {
  cors: { origin: 'https://your-frontend-url.com' }
});

// Validate token on socket connection (mirror your API's auth logic)
io.use((socket, next) => {
  const token = socket.handshake.auth.token;
  if (!token) return next(new Error('No auth token provided'));

  jwt.verify(token, process.env.JWT_SECRET, (err, decoded) => {
    if (err) return next(new Error('Invalid token'));
    socket.userId = decoded.userId; // Attach user ID to socket for targeted pushes
    next();
  });
});

// Join user to a unique room for targeted notifications
io.on('connection', (socket) => {
  console.log(`User ${socket.userId} connected`);
  socket.join(`user-${socket.userId}`);

  socket.on('disconnect', () => {
    console.log(`User ${socket.userId} disconnected`);
    socket.leave(`user-${socket.userId}`);
  });
});

// Helper function to send notifications to a specific user
const sendUserNotification = (userId, notification) => {
  io.to(`user-${userId}`).emit('new-notification', notification);
};

// Call this function whenever your API creates a new notification
// Example: After saving a notification to your database
app.post('/api/notifications', (req, res) => {
  const newNotification = {
    id: Date.now(),
    message: req.body.message,
    userId: req.body.userId,
    timestamp: new Date()
  };
  // Save to DB...
  sendUserNotification(newNotification.userId, newNotification);
  res.status(201).json(newNotification);
});

server.listen(3001, () => console.log('Socket server running on port 3001'));

Option 2: Server-Sent Events (SSE) – Lightweight for Unidirectional Updates

If you don’t need two-way communication (e.g., you don’t need to send "mark as read" events back in real-time), SSE is a simpler, HTTP-based alternative. It’s built into browsers and requires no extra libraries for the frontend.

Frontend Implementation

import { useEffect, useState } from 'react';

const SSENotifications = () => {
  const [notifications, setNotifications] = useState([]);

  useEffect(() => {
    const userToken = localStorage.getItem('authToken');
    const eventSource = new EventSource(`https://your-backend-url.com/api/notifications/sse?token=${userToken}`);

    // Handle incoming notifications
    eventSource.onmessage = (event) => {
      const newNotification = JSON.parse(event.data);
      setNotifications(prev => [newNotification, ...prev]);
    };

    // Handle errors
    eventSource.onerror = (err) => {
      console.error('SSE connection error:', err);
      eventSource.close();
    };

    // Clean up on unmount
    return () => eventSource.close();
  }, []);

  return (
    <div className="notifications-container">
      <h3>SSE Real-Time Notifications</h3>
      {notifications.length === 0 ? (
        <p>No new notifications</p>
      ) : (
        notifications.map(notification => (
          <div key={notification.id} className="notification-item">
            <p>{notification.message}</p>
            <small>{new Date(notification.timestamp).toLocaleString()}</small>
          </div>
        ))
      )}
    </div>
  );
};

export default SSENotifications;

Backend SSE Endpoint (Node.js/Express)

app.get('/api/notifications/sse', (req, res) => {
  // Set SSE headers
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');
  res.setHeader('Access-Control-Allow-Origin', 'https://your-frontend-url.com');

  // Validate token
  const token = req.query.token;
  jwt.verify(token, process.env.JWT_SECRET, (err, decoded) => {
    if (err) {
      res.write('event: error\ndata: Invalid auth token\n\n');
      res.end();
      return;
    }
    const userId = decoded.userId;

    // Simulate listening for new notifications (replace with your DB/queue logic)
    const notificationInterval = setInterval(async () => {
      // Fetch latest unread notifications for the user
      const latestNotification = await Notification.findOne({ userId, read: false }).sort({ timestamp: -1 });
      if (latestNotification) {
        res.write(`data: ${JSON.stringify(latestNotification)}\n\n`);
        // Mark as read if needed
        await Notification.findByIdAndUpdate(latestNotification._id, { read: true });
      }
    }, 2000);

    // Clean up when client disconnects
    req.on('close', () => {
      clearInterval(notificationInterval);
      res.end();
    });
  });
});

Which Option Should You Pick?

  • Socket.io: Use this if you need two-way real-time communication (e.g., instantly marking notifications as read, or sending user actions back to the server).
  • SSE: Use this for simple, one-way updates (like just receiving new notifications)—it’s lighter and requires less setup.

Neither option requires rewriting your existing React project—you can drop these components in alongside your current code and replace the setInterval polling with the real-time solution.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 23:37:33