【问题标题】:How to receive SocketIO events in React while using states使用状态时如何在 React 中接收 SocketIO 事件
【发布时间】:2021-04-03 16:54:49
【问题描述】:

这是我的代码的一部分,我想做的是这个组件可以随时接收任何对话的消息。发送消息会触发 Socket 事件,该事件会触发下面的代码,但我似乎无法获得“最新”对话,因为 useEffect 仅在组件安装时触发(此时我的对话数组的长度为零)。

我的想法是我应该在 useEffect 的依赖项中包含“对话”,但这会创建多个 websocket 连接,每次触发 Socket.io 事件时都会创建一个连接,因为它确实会改变状态。这是最好的解决方案吗?提前致谢!

const [conversations, setConversations] = useState<Array<Conversations>>([]);

useEffect(() => {
    async function getConversations() {
      try {
        const { data } = await axios.get("/api/conversations/");

        if (data.success) {
          setConversations(data.details);
        }
      } catch (err) {}
    }

    getConversations();

    socketInstance.on("connect", () => {
      console.log("Connecting to Sockets...");
      socketInstance.emit("authenticate", Cookies.get("token") || "");
    });

    socketInstance.on("ackAuth", ({ success }) => {
      console.log(
        success
          ? "Successfully connected to Sockets"
          : "There has been an error connecting to Sockets"
      );
    });

    socketInstance.on("newMessage", (data) => {
        const modifiedConversation: Conversations = conversations.find(
      (conv: Conversations) => {
        return conv.conversationId === data.conversationId;
      }
    );

    modifiedConversation.messages.push({
      from: {
        firstName: data.firstName,
        lastName: data.lastName,
        profilePhoto: data.profilePhoto,
        userId: data.userId,
      },
      content: data.content,
      timeStamp: data.timeStamp,
    });

    const updatedConversations = [
      ...conversations.filter(
        (conv) => conv.conversationId !== data.conversationId
      ),
      modifiedConversation,
    ];

    setConversations(updatedConversations);
    });
  }, []);

【问题讨论】:

    标签: javascript reactjs socket.io use-effect use-state


    【解决方案1】:

    虽然每次conversations 更改时都可以附加和删除套接字侦听器,但更好的选择是使用设置器的回调形式。幸运的是,您仅在引用状态时继续更新状态。你可以改变

    socketInstance.on("newMessage", (data) => {
      const modifiedConversation: Conversations = conversations.find(
      // lots of code
      setConversations(updatedConversations);
    

    socketInstance.on("newMessage", (data) => {
      setConversations(conversations => {
        const modifiedConversation: Conversations = conversations.find(
        // lots of code
        setConversations(updatedConversations);
    

    你也不应该改变状态,因为这是 React。而不是

    modifiedConversation.messages.push({
    

    const modifiedConversationWithNewMessage = {
      ...modifiedConversation,
      messages: [
        ...modifiedConversation.messages,
        {
          from: {
            // rest of the object to add
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-15
      • 2020-11-10
      • 2022-01-23
      • 2021-03-25
      • 2018-11-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多