【问题标题】:How to loop through an updating array in react如何在反应中循环更新数组
【发布时间】:2021-10-04 18:58:31
【问题描述】:

我正在尝试使用React.js 练习socket.io,因此我尝试在两个客户端之间发送消息,但是我在显示消息时遇到了困难。我想显示过去发送的消息。现在我正在考虑将它作为一个数组来做,因为一个状态不起作用。当控制台记录数组时,它会显示在控制台中,但永远不会呈现出来

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("");
  var itemArray = [];

  useEffect(() => {
    //connect to the socket
    socket = io(CONNECTION_PORT);

    socket.on("receive-message", (data) => {
      itemArray.push(data);
      console.log("Pong");
      console.log(itemArray);
    });

    //receiving messages
    socket.on("authentication", (bool) => {
      if (bool === true) {
        setLoggedIn(true);
      }
    });
  }, [CONNECTION_PORT]);

  //Sending a request to join the room
  const connectToRoom = () => {
    socket.emit("join-room", room, userName);
  };

  const sendMessage = () => {
    socket.emit("send-message", message);
  };

  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..."
            onChange={(e) => {
              setMessage(e.target.value);
            }}
          />
          <button onClick={sendMessage}>Send Message</button>
          <div>
            {itemArray.map((data) => {
              console.log(data);
            })}
          </div>
        </div>
      )}
    </div>
  );
}
export default App;

【问题讨论】:

    标签: javascript arrays reactjs rendering


    【解决方案1】:

    数组正在更新,但没有什么可以告诉 React 渲染更新。任何这些更改都会导致组件再次呈现:

    1. 道具更新
    2. 状态更新
    3. Context 值变化

    React DOM 将元素及其子元素与前一个元素进行比较,并且仅应用必要的 DOM 更新以使 DOM 达到所需状态。

    您正在更新组件中的数组变量,但这不会触发渲染。将数组移入状态:

    const [messages, setMessages] = useState([]);
    ...
    useEffect(() => {
        ...
        socket.on("receive-message", (data) => {
          // update the state which triggers a render
          setMessages(prevState => [...prevState, data]);
        });
    
    }, [CONNECTION_PORT]);
    
    

    【讨论】:

    • 好吧,当 A 发送一条消息它发送它并且 B 接收但如果 B 发送回一条消息它会刷新它多次时,这有效
    • 多次刷新是什么意思?这听起来像是消息被多次发出——console.log 来确定。
    • 没关系,我更改了控制台日志。现在这段代码的结果是,当 A 发送多条消息时,它会显示它和 B 的最后一条消息,但是一旦 B 发送一条消息,它就会清除 A 的消息。但是,对于接收消息,它会替换最后一条消息,并且不会像发件人那样堆叠
    • 好的,但我们现在要解决另一个问题,即正确地向房间里的人发送消息。问题不在于updating array in react 并让它渲染。 两个客户端都需要接收消息 (receive-message),以便他们可以更新其相关状态。
    • 怎么样?据我了解...messages 获取消息的最后状态并将新数据添加到数组中?但是在我的情况下,它没有收到收到的消息的最后一个状态,它只是添加它
    【解决方案2】:

    需要返回数据才能看到 Map 返回您遍历的每个值,因此您必须确保说您想查看列表中的数据 请务必这样返回

    内部地图功能

    {itemArray.map((data) => {
                  return<li>{data.propertyName}</li>
                })}
    

    这里的属性可以是对象属性的任何东西

    【讨论】:

    • 问题是如果itemArray 变量被更新,组件将不会重新渲染
    • 尝试使用带有第二个参数的useEffect作为更新后的数组
    • 另外,数组是 JavaScript 中的对象,因此更改它并不意味着组件会知道它已更改,您需要使用标志和 r例如 reRender true false 并将其用作参考,这样它会看到有一个变化,否则它不会影响上一个因为对象仍然是 JavaScript 中的对象
    猜你喜欢
    • 1970-01-01
    • 2016-05-20
    • 2020-01-24
    • 2019-11-20
    • 2020-09-16
    • 1970-01-01
    • 2019-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多