React中Socket.io倒计时重复运行问题求助(附服务端与客户端代码)
问题分析
你的核心问题是服务端每有新客户端连接(包括页面刷新)就会启动一个独立的倒计时定时器:
- 首次启动时只有1个定时器,所以倒计时按1秒间隔正常显示;
- 刷新页面后,旧连接未及时销毁,加上新连接会创建第2个定时器,两个定时器同时每秒发送不同的倒计时数值,客户端同时接收两个流,就会出现0.5秒更新一次、数值混乱的情况。
修正方案
服务端代码(index.js)
将倒计时逻辑改为全局单例模式,避免重复创建定时器:
const express = require('express'); const app = express(); const http = require("http"); const { Server } = require('socket.io'); const cors = require("cors") app.use(cors()) const server = http.createServer(app) const io = new Server(server, { cors: { origin: "http://localhost:3000", methods: ["GET", "POST"], }, }); // 全局维护倒计时状态与定时器实例 let counter = 10; let winnerCountdown = null; // 单例启动倒计时 function startCountdown() { if (winnerCountdown) return; // 防止重复启动 winnerCountdown = setInterval(() => { io.sockets.emit('counter', counter); counter--; if (counter === 0) { io.sockets.emit('counter', "Congratulations You WON!!"); clearInterval(winnerCountdown); winnerCountdown = null; // 重置状态,可按需重启 } }, 1000); } // 服务启动时初始化倒计时 startCountdown(); io.on('connection', function(socket){ // 新连接时立即发送当前倒计时数值,避免客户端初始空白 socket.emit('counter', counter); }); server.listen(3001, () => { console.log("SERVER IS RUNNING"); });
客户端代码(App.js)
添加监听清理逻辑,避免重复监听导致的多次更新:
import { useState, useEffect } from 'react'; import io from 'socket.io-client'; const socket = io.connect("http://localhost:3001"); const App = () => { const [counter, setCounter] = useState(); useEffect(() => { const handleCounter = (newCounter) => { setCounter(newCounter); console.log("test"); }; socket.on("counter", handleCounter); // 组件卸载时移除监听,防止内存泄漏 return () => { socket.off("counter", handleCounter); }; }, []); // 空依赖确保监听只绑定一次 return ( <h1>{counter}</h1> ); } export default App;
关键修正点
- 服务端:将定时器移到连接事件外部,全局只启动一次,新连接仅同步当前倒计时数值,不再创建新定时器;
- 客户端:使用
socket.off在组件卸载时移除监听,避免重复绑定导致的多次状态更新。
内容的提问来源于stack exchange,提问作者Venoz
相关产品推荐
相关产品推荐

