Next.js集成Socket.io遇代码重复执行问题求助
Next.js集成Socket.io操作执行两次的解决办法
问题根源
你遇到的两次执行问题,核心原因是Next.js开发模式下的React Strict Mode——它会刻意重复调用组件的渲染逻辑和副作用函数,用来检测潜在的代码问题。你现在把socket初始化直接写在组件函数里,每次组件渲染都会执行这段代码,哪怕加了typeof window !== 'undefined',Strict Mode还是会触发两次。
解决步骤
- 用useEffect包裹socket初始化逻辑
把socket的创建和事件触发放到useEffect里,并且设置空依赖数组[],确保这段代码只在组件挂载时执行一次。 - 添加组件卸载时的清理逻辑
在useEffect的返回函数里断开socket连接,避免组件卸载后残留无效连接,造成内存泄漏。
修改后的代码示例
import Navbar from "@/components/navbar"; import { fetchUserInfo } from "@/utils/fetchUserInfo"; import { io } from 'socket.io-client'; import { config } from 'dotenv'; import { useEffect } from 'react'; // 导入useEffect import getSocket from "@/components/getSocket"; config({path: '../.env.development.local'}) export async function getServerSideProps(context){ const { cookie } = context.req.headers; if (context.req.cookies['gameStatus'] === undefined){ return{ notFound: true } } else{ const {displayName, userAvatar, isCookieAvailable} = await fetchUserInfo(cookie) return{ props: { displayName, userAvatar, isCookieAvailable } } } } export default function Game({displayName, userAvatar, isCookieAvailable}){ useEffect(() => { // 仅在客户端执行,且组件挂载时仅运行一次 const socket = io(process.env.NEXT_PUBLIC_SERVER_URL); console.log('here'); socket.emit('event', 'eventlog'); // 组件卸载时断开socket连接 return () => { socket.disconnect(); }; }, []); // 空依赖数组确保逻辑仅执行一次 return( <> <Navbar displayName={displayName} userAvatar={userAvatar} isCookieAvailable={isCookieAvailable}/> : {!isCookieAvailable && <div style={{color: 'white'}}>Not logged in please login</div>} </> ) }
额外说明
- 开发模式下的Strict Mode重复执行是正常现象,生产环境打包后Strict Mode会自动关闭,不会出现两次执行的问题。
- 如果需要全局复用socket实例,可以把socket初始化逻辑封装到单独的hooks里(比如你导入的
getSocket),确保整个应用只创建一个socket连接,避免重复实例化。
内容的提问来源于stack exchange,提问作者Lupin
相关产品推荐
相关产品推荐

