Javascript 如何在使用状态时在React中接收SocketIO事件

Javascript 如何在使用状态时在React中接收SocketIO事件,javascript,reactjs,socket.io,use-effect,use-state,Javascript,Reactjs,Socket.io,Use Effect,Use State,这是我代码的一部分,我想做的是这个组件在任何时候都可以在任何对话中接收消息。发送消息会触发一个套接字事件,该事件会触发下面的代码,但我似乎无法获取“最新”的对话,因为useEffect仅在组件装载时触发(此时我的对话数组的长度为零) 我的想法是,我应该在useEffect的依赖项中包含“对话”,但这会创建多个websocket连接,每次触发Socket.io事件时都会创建一个websocket连接,因为它确实会更改状态。这是最好的解决方案吗?提前谢谢 const [conversations,

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

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

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);
    });
  }, []);
const[conversations,setConversations]=useState([]);
useffect(()=>{
异步函数getConversations(){
试一试{
const{data}=wait axios.get(“/api/conversations/”);
if(data.success){
setConversations(data.details);
}
}捕获(错误){}
}
getConversations();
socketInstance.on(“连接”,()=>{
日志(“连接到套接字…”);
socketInstance.emit(“身份验证”、Cookies.get(“令牌”)| |“);
});
socketInstance.on(“ackAuth”,({success})=>{
console.log(
成功
?“已成功连接到插座”
:“连接到套接字时出错”
);
});
socketInstance.on(“新消息”,(数据)=>{
const modifiedConversation:Conversations=Conversations.find(
(会话)=>{
返回conv.conversationId==data.conversationId;
}
);
modifiedConversation.messages.push({
发件人:{
firstName:data.firstName,
lastName:data.lastName,
profilePhoto:data.profilePhoto,
userId:data.userId,
},
内容:data.content,
timeStamp:data.timeStamp,
});
const updatedConversations=[
…会话.筛选器(
(conv)=>conv.conversationId!==data.conversationId
),
修改的转换,
];
setConversations(更新的Conversations);
});
}, []);

虽然每次
对话
更改时都可以附加和删除套接字侦听器,但更好的选择是使用setter的回调形式。幸运的是,只有在引用状态时,才能继续更新状态。你可以改变

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

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

modifiedConversation.messages.push({

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