Socket.io与Redux工具包不同步

t98cgbkg  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(100)

我有一个类似于WhatsApp Web的聊天应用程序。聊天部分在左侧和中间显示所有聊天。默认情况下,当用户登录时,第一个联系人被存储为selectedChatUser
我存储所有的聊天发送到用户在postgres数据库中,无论用户是否在线。我在App中有两个事件:从后端检测到send-msg和receive-msg . send-msg is emitted from frontend side and receive-msg is emitted from backend. I try to call the getUserAllMessage()to get all the chats from db whenever frontend detects receive-msg事件。 我不知道为什么当received-msg事件调用getUserAllMessage()方法时,我直接从selectedChatUser存储对象中获取的to`字段为空。下面是我的代码:
ChatContainer.jsx:

import React,{useState,useEffect} from "react";
import { useSelector } from 'react-redux';
import { getMessage } from "../../services/messageService";

function ChatContainer() {
  const loggedInUserEmail = useSelector(state=>state.loggedInUser.emailId);
  const selectedChatUser = useSelector(state=>state.selectedChatUser.selectedChatUser);
  const socket = useSelector(state=>state.socket.socket);
  const [userAllMessages, setUserAllMessages] = useState([]);

  useEffect(()=>{
    if(!socket)return;
    socket.on('msg-receieved',async ()=>{
      console.log("message received: ",userAllMessages);
      await getUserAllMessage(); //problem arises here
    })
  },[socket])
  useEffect(()=>{
    getUserAllMessage();
  },[selectedChatUser])
  const getUserAllMessage = async ()=>{
    let payload = {
      from:loggedInUserEmail,
      to:selectedChatUser?.email   // IDK why this field gets empty even the selectedChatUser is set in redux store previously
    }
    try {
      const response = await getMessage(payload);      
      if(response.data.status === 200){
        console.log("user messages",response.data);
        setUserAllMessages(response.data.messages);
      }
      else{
        console.log("Error while getting user messages: ",response.data);
      }
    } catch (error) {
       console.log("Error while getting user messages: ",error);
    }
  }
  return <div className="overflow-auto custom-scrollbar relative w-full flex-grow h-full">
    <div className="bg-chat-background bg-fix h-full w-full absolute top-0 opacity-5 z-0"></div>
    <div className="mx-10 my-6  z-40">
    <div className="flex w-full">
      <div className="flex flex-col justify-end gap-1 w-full overflow-auto">
        {userAllMessages.map((message,index)=>(
          <div key={index}
          className={`flex ${message.senderId === loggedInUserEmail ? "justify-end":"justify-start"}`}
          >
              <div className={`text-white px-2 py-[5px] text-sm rounded-md flex gap-2 items-end max-w-[45%] ${message.senderId === selectedChatUser?.email ? "bg-input-background":"bg-outgoing-background"} `}>
                  <span className="break-all">{message?.message}</span>
              </div>
          </div>
        ))}
      </div>
    </div>
    </div>
  </div>;
}

export default ChatContainer;

ContactsList.jsx:

import React,{useState,useEffect} from "react";
import { useSelector, useDispatch } from 'react-redux';
import {setSelectedChatUser} from "../../store/chatSlice";
import {getAllContacts} from "../../services/userService";
import List from "./List";

function ContactsList() {
  const loggedInUser = useSelector(state=>state.loggedInUser.emailId);
  const dispatch = useDispatch();
  const [allUserContacts, setAllUserContacts] = useState([]);

  useEffect(()=>{
    getUserAllContactsList()
  },[])
  const getUserAllContactsList = async ()=>{
    let payload={
      email:loggedInUser
    }
    try {
      const response = await getAllContacts(payload);
      if(response.data.status === 200){
        console.log(response.data.users);
        setAllUserContacts(response.data.users)
        if(response.data.users?.length > 0){
          dispatch(setSelectedChatUser(response.data.users[0]));   //setting the first chat as the default selected chat user
        }
      }
      else{
        console.log("Error while fetching contacts: ",response.data)
      }
    } catch (error) {
      console.log("Error while fetching contacts: ",error);
    }
  }
  return <div className="bg-transparent max-h-screen overflow-auto">
    {allUserContacts.map((user,index)=>(
      <List key={index} profilePic={user?.image || '/avatars/1.png'} name={user.name} message={''} email={user.email} onClick={()=>dispatch(setSelectedChatUser(user))}/>
    ))}
  </div>;
}

export default ContactsList;

我不知道我的代码发生了什么,为什么会发生。这是我第一次使用socket.io和redux。我已经在问题所在添加了注解。如果有人知道我在哪里犯了错误,请告诉我。
谢谢

vohkndzv

vohkndzv1#

当你订阅事件msg-receieved时,它会创建一个函数getUserAllMessage()的副本,此时你的状态selectedChatUser为空.所以当你接收到msg-receieved事件并且getUserAllMessage()被调用时,它有selectedChatUser空.尝试订阅msg-received事件时,你有selectedChatUser值.

相关问题