React结合Socket.io开发出现Socket连接无限循环重连如何解决?
无限循环产生原因
你代码的死循环是React useEffect依赖项设置错误触发的连锁反应:
- 你的useEffect把
chat设为了依赖项,每次chat值更新都会触发useEffect重新执行 - 首次执行useEffect时,会新建socket连接、发送online事件,后端广播online事件后,前端触发对应监听调用
setChat更新chat数组 - chat更新后触发useEffect重新执行,执行前会先运行清理函数断开旧socket连接,后端检测到断开就打印offline日志、广播offline事件
- 新的useEffect执行又会新建socket连接、再次发送online事件,后端再次打印online日志,前端再次更新chat,循环往复
- 你删除online、offline事件的监听后,不再触发setChat更新chat,useEffect不会重复执行,死循环自然消失,和你测试的现象完全吻合。
解决方法
不需要删除事件监听,只需要修改前端useEffect的逻辑即可:
- 移除useEffect依赖中的
chat,避免chat更新触发socket重连 - 所有
setChat调用改为函数式更新,规避闭包问题,不需要依赖chat也能拿到最新的聊天记录值
修改后的前端代码参考:
useEffect(() => { socketRef.current = io.connect("...", { transports : ['websocket'] }) socketRef.current.emit("online", id) socketRef.current.on("message", ({ name, message }) => { setChat(prevChat => [ ...prevChat, { name, message , system: false } ]) }) socketRef.current.on("online", ( userID ) => { setChat(prevChat => [ ...prevChat, { name: userID , message: `has logged on` , system: true } ]) }) socketRef.current.on("offline", ( userID ) => { setChat(prevChat => [ ...prevChat, { name: userID , message: `${userID} has logged off` , system: true } ]) }) return () => { socketRef.current.disconnect() } },[ id ]) // 如果id是固定不变的,也可以直接放空数组作为依赖
内容的提问来源于stack exchange,提问作者shenny tan
相关产品推荐
相关产品推荐

