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

React结合Socket.io开发时如何遍历渲染实时更新的消息数组?

问题原因

你遇到的渲染失效问题主要有两个核心原因:

  • 普通变量不具备响应式能力:React仅会在useState、useReducer等声明的响应式状态更新时触发组件重新渲染,你声明的itemArray是组件内的普通临时变量,不仅修改它不会触发页面更新,每次组件重渲染时还会被重置为空数组。
  • 遍历逻辑没有返回渲染内容:你在itemArray.map的回调中仅执行了console.log操作,没有返回任何要渲染的UI元素,就算数组有内容也不会在页面展示。

修正后完整代码

import { useEffect, useState } from "react";
import io from "socket.io-client";
import "./App.css";

let socket;
const CONNECTION_PORT = "localhost:3001/";

function App() {
  const [loggedIn, setLoggedIn] = useState(false);
  const [room, setRoom] = useState("");
  const [userName, setUserName] = useState("");
  const [message, setMessage] = useState("");
  // 用useState声明响应式的消息列表
  const [messageList, setMessageList] = useState([]);

  useEffect(() => {
    socket = io(CONNECTION_PORT);

    const handleReceiveMessage = (data) => {
      // 不可变方式更新消息列表,触发组件重渲染
      setMessageList(prev => [...prev, data]);
      console.log("Pong");
    };

    const handleAuthentication = (bool) => {
      if (bool === true) {
        setLoggedIn(true);
      }
    };

    socket.on("receive-message", handleReceiveMessage);
    socket.on("authentication", handleAuthentication);

    // 组件卸载时清理监听、断开连接,避免内存泄漏
    return () => {
      socket.off("receive-message", handleReceiveMessage);
      socket.off("authentication", handleAuthentication);
      socket.disconnect();
    };
  }, [CONNECTION_PORT]);

  const connectToRoom = () => {
    socket.emit("join-room", room, userName);
  };

  const sendMessage = () => {
    socket.emit("send-message", message);
    // 发送后清空输入框
    setMessage("");
  };

  return (
    <div className="App">
      {!loggedIn ? (
        <div className="login">
          <input
            type="text"
            placeholder="Name..."
            onChange={(e) => setUserName(e.target.value)}
          />
          <input
            type="text"
            placeholder="Room..."
            onChange={(e) => setRoom(e.target.value)}
          />
          <button onClick={connectToRoom}> Enter Chat</button>
        </div>
      ) : (
        <div>
          <input
            type="text"
            placeholder="Send Message..."
            value={message}
            onChange={(e) => setMessage(e.target.value)}
          />
          <button onClick={sendMessage}>Send Message</button>
          <div className="message-box">
            {/* 遍历返回消息元素,添加唯一key */}
            {messageList.map((data, index) => (
              <p key={index}>{data}</p>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}
export default App;

补充说明

如果需要展示消息发送者信息,可以调整服务端广播逻辑,把{ content: 消息内容, sender: 用户名 }这类结构化数据传递到前端,渲染时分别展示即可。

内容的提问来源于stack exchange,提问作者James Westhead

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 01:39:03