首页 > 解决方案 > firestore 没有通过反应分离侦听器

问题描述

我正在使用 firebase firestore 数据库和 reactjs 构建一个聊天应用程序

我正在尝试使用反应挂钩来管理数据流,但在分离 firestore 侦听器时遇到了麻烦。

这个使用效果是我初始化监听器的地方。

useEffect(() => {
    setMessages(null)

    roomId && listenForMessages(roomId, setMessages, false, scrollToBottom)
    return () => {
      if (active && setMessages) {
        //Detach here
        listenForMessages(roomId, setMessages, true)
      }
    }
  }, [roomId ])

这是我的监听器功能

export const listenForMessages = (roomId, setMessages, detach, scrollToBottom) => {
  let listener = db
    .collection('chats')
    .doc(roomId)
    .collection('messages')
    .orderBy('timestamp')
    .onSnapshot(
      docSnapshot => {
        let data = []
        docSnapshot.docs.forEach(doc => data.push({ id: doc.id, ...doc.data() }))
        setMessages(data)
        scrollToBottom()
      },
      err => {
        console.log(`Encountered error: ${err}`)
      }
    )
  if (detach === true) {
    listener()
  }
}

这个 dosnt 似乎分离了以前附加的侦听器。就好像我打开聊天室A然后导航到聊天室B并且聊天室A收到一条消息,它会调用写消息。

标签: reactjsfirebasegoogle-cloud-firestore

解决方案


这最终起作用了,但如果有人可以重组它让我知道,它不是很干净。

我已经确定初始代码正在关闭侦听器,但再次调用 listenForMessages() 函数来关闭它正在打开另一个侦听器。

useEffect(() => {
    setMessages(null)
    let listener
    if (active) {
      listener = db
        .collection('chats')
        .doc(active)
        .collection('messages')
        .orderBy('timestamp')
        .onSnapshot(
          docSnapshot => {
            let data = []
            docSnapshot.docs.forEach(doc => data.push({ id: doc.id, ...doc.data() }))
            setMessages(data)
            scrollToBottom()
          },
          err => {
            console.log(`Encountered error: ${err}`)
          }
        )
    }
    return () => {
      if (active) {
        listener()
      }
    }

    //eslint-disable-next-line
  }, [active])

推荐阅读