0

每当我通过 onSnapshot 从消息集合中提取新消息时,我的消息收件箱都不会重新呈现。

正如我在开发工具中看到的那样,我可以确认新消息肯定存储在 auseRef中,但是该消息没有进入 DOM。

我遵循zustand's了解释使用 ref 的文档,并且建议使用他们的订阅方法来重复发生状态更改:https ://github.com/pmndrs/zustand#transient-updates-for-often-occuring-state-changes

谁能看到我可能出错的地方?

获取对话和实时更新的消息页面

import { useState, useEffect, useRef } from "react";
import "./Messages.scss";
import { db } from "../../firebase";
import { Message, Conversation } from "../../Interfaces/Interfaces";
import MessagesHeader from "./Components/MessagesHeader/MessagesHeader";
import MessagesConversations from "./Components/MessagesConversations/MessagesConversations";
import create from "zustand";
import authStore from "../../Global/AuthState/AuthStore";

interface ConversationsStore {
  conversations: Array<Conversation>;
  setConversations: (newConversations: Array<Conversation>) => void;
}

const conversationsStore = create<ConversationsStore>((set) => ({
  conversations: [],
  setConversations: (newConversations: Array<Conversation>) =>
    set({ conversations: newConversations }),
}));

function Messages() {
  const currentUser = authStore((state) => state.currentUser);
  const [subToUpdates, setSubToUpdates] = useState<boolean>(false);
  const [initialDone, setInitialDone] = useState<boolean>(false);
  //create the initial conversations ref
  const conversationsRef = useRef<Array<Conversation>>(
    conversationsStore.getState().conversations
  );
  const conversations = conversationsStore((state) => state.conversations);
  const setConversations = conversationsStore(
    (state) => state.setConversations
  );

  //zustand's recommended subscribe useEffect to re-render whenever a new conversation enters the db
  useEffect(
    () =>
      conversationsStore.subscribe(
        (state) => (conversationsRef.current = state.conversations)
      ),
    []
  );

  //get the current conversations that the user is in
  useEffect(() => {
    if (currentUser) {
      let initialConversations: Array<Conversation> = [];
      const conversationsRef = db.collection("conversations");
      const getInitialConversations = async () => {
        const conversationsSnapshot = await conversationsRef
          .where("users", "array-contains", currentUser.uid)
          .orderBy("latestMessageDate", "desc")
          .get();
        conversationsSnapshot.forEach((doc) => {
          let tempConversation: Conversation = doc.data() as Conversation;
          tempConversation.conversationId = doc.id;
          initialConversations.push(tempConversation);
          setConversations(initialConversations);
        });
      };
      getInitialConversations().then(() => setSubToUpdates(true));
    }
  }, [currentUser]);

  //after the initial load, listen to changes in the firestore collection
  useEffect(() => {
    if (subToUpdates && currentUser && !initialDone) {
      setInitialDone(true);
    } else if (subToUpdates && currentUser && initialDone) {
      const conversationsRef = db.collection("conversations");
      return conversationsRef
        .where("users", "array-contains", currentUser.uid)
        .orderBy("latestMessageDate", "desc")
        .limit(1)
        .onSnapshot((querySnapshot) => {
          console.log("new conversation found");
          querySnapshot.forEach((doc) => {
            {
              /* 
            let tempConversations = conversations?.filter(
              (currentConversation) =>
                currentConversation.conversationId == doc.id
            );
            */
            }
            let tempConversations = conversations;
            let tempConversation: Conversation = doc.data() as Conversation;
            tempConversation.conversationId = doc.id;
            tempConversations?.push(tempConversation);
            setConversations(tempConversations);
          });
        });
    }
  }, [subToUpdates, initialDone]);

  return (
    <div className="messages">
      {conversations.length > 0 &&
        conversations.map((conversation, index) => (
          <h4 key={index}>{conversation.latestMessage.message}</h4>
        ))}
      <MessagesHeader />
      <MessagesConversations
        conversations={conversationsRef.current}
        filterByUnread={false}
      />
    </div>
  );
}

export default Messages;

映射对话并显示它们的收件箱对话容器

import React from "react";
import "./MessagesConversations.scss";
import MessagesConversationsConversation from "./Components/MessagesConversationsConversation/MessagesConversationsConversation";
import { Conversation } from "../../../../Interfaces/Interfaces";

interface Props {
  conversations: Array<Conversation> | undefined;
  filterByUnread: boolean;
}

function MessagesConversations({ conversations, filterByUnread }: Props) {
  return (
    <div className="messagesConversations">
      {conversations !== undefined &&
        (conversations?.length > 0 ? (
          conversations.map((conversation) => (
            <MessagesConversationsConversation
              conversation={conversation}
              key={`conversation__${conversation.conversationId}`}
            />
          ))
        ) : (
          <h4>No messages</h4>
        ))}
    </div>
  );
}

export default MessagesConversations;
4

0 回答 0