React useState和Firebase on Snapshot

y4ekin9u  于 2023-08-07  发布在  React
关注(0)|答案(4)|浏览(132)

我想使用onSnapshot从firestore集合中自动获取新的传入消息。虽然我可以在回调中设置状态,但我无法读取它。

const [messages, setMessages] = useState(null);
const [chat, setChat] = useState(props.chatId);

useEffect(() => {
        const q = query(collection(db, "messages"), where("chat_id", "==", chat), orderBy("date","desc"), limit(5));
        // Create the DB listener
        const unsuscribe = onSnapshot(q, (querySnapshot) => {
            console.log(messages);
            if(messages === null){
                console.log("setting messages the first time");
                setMessages(querySnapshot.docs)
            }else{
                console.log("updating messages");
                setMessages([...querySnapshot.docs, ...messages])
            }
        });
        return () => {
            console.log("unsubscribe");
            unsuscribe();
        }
    }, [chat]);

字符串
每当onSnapshot触发时,messages始终为null,但setMessages工作,因为消息显示。我尝试了很多方法,但我不能让它工作。
非常感谢帮助。

cyej8jka

cyej8jka1#

所以我设法找到了解决办法。诀窍是用useEffect()监听消息的状态变化

const [snapShot, setSnapshot] = useState(null);
const [messages, setMessages] = useState(null);
const [chat, setChat] = useState(props.chatId);

useEffect(() => {
        const q = query(collection(db, "messages"), where("chat_id", "==", chat), orderBy("date","desc"), limit(5));
       
        const unsuscribe = onSnapshot(q, (querySnapshot) => {
            setSnapShot(querySnapshot)
        });
        return () => {
            unsuscribe();
        }
    }, [chat]);

useEffect(() => {
  if(messages === null){
                console.log("setting messages the first time");
                setMessages(snapShot.docs)
            }else{
                console.log("updating messages");
                setMessages([...snapShot.docs, ...messages])
            }
    }, [snapShot]);

字符串

8cdiaqws

8cdiaqws2#

你有没有从documentation尝试过这个

const q = query(collection(db, "cities"), where("state", "==", "CA"));
const unsubscribe = onSnapshot(q, (snapshot) => {
  snapshot.docChanges().forEach((change) => {
    if (change.type === "added") {
        console.log("New city: ", change.doc.data());
    }
    if (change.type === "modified") {
        console.log("Modified city: ", change.doc.data());
    }
    if (change.type === "removed") {
        console.log("Removed city: ", change.doc.data());
    }
  });
});

字符串
另外,这个问题有点让人困惑,你想达到什么目的

btxsgosb

btxsgosb3#

您从Firestore获取的querySnapshot始终包含与查询匹配的所有快照,而不仅仅是更改的/新的文档。
所以你的onSnapshot处理程序可以简单得多:

const unsubscribe = onSnapshot(q, (querySnapshot) => {
    setMessages(querySnapshot.docs)
});

字符串
因此:每次Firestore通知您q中的数据已更改时,您都会将数据传递到状态/UI进行渲染。

hjqgdpho

hjqgdpho4#

它显示为null,因为当您创建快照回调时,它使用的是属于该渲染的值。类似于尝试在事件回调中访问useState值。
标签:https://stackoverflow.com/a/55265764/8846296
一个解决方案是使用useRef而不是useState来存储值。然后您可以在回调中使用myValue.current访问它

相关问题