useEffect 钩子中的异步/等待不等待函数

时间:2021-02-24 18:29:04

标签: javascript reactjs react-native asynchronous google-cloud-firestore

正如标题所说。我正在为我的聊天服务使用 firestore。我正在尝试设置一种方法来在 Firestore 更新时过滤掉消息

/tmp/

await 不等待 getIDs 函数,并且 const users = useSelector((state) => state.assignUser); const [messages, setMessages] = useState([]); const chatID = 'KfM3GNxeVATi6sNFFUEG' function getIDs(messageObj){ return messageObj.map(message => message._id) } useEffect(() => { const messagesArray = [] db.collection('messages').doc(chatID).collection('messages').get().then(snapshot => { snapshot.forEach(doc => messagesArray.push(doc.data())) setMessages(messagesArray) async function fetchMessages(){ const messageIDs = await getIDs(messages) db.collection('messages').doc(chatID).collection('messages').onSnapshot(doc => { doc.forEach((document) => { if (messageIDs.indexOf(document.data()._id !== -1)) console.log('the is is ', messageIDs.indexOf(document.data()._id)) else console.log('notfoundssw') }) }) } fetchMessages() }) }, []) 的日志对于每个条目都是 -1。我不明白为什么 async/await 错误行为

2 个答案:

答案 0 :(得分:3)

您的 messagesIDs 变量取决于消息状态更新,这不会发生同步。根据您的代码结构,您必须打破 2 useEffects。第一个更新 mount 上的消息,第二个监听消息更新:

  useEffect(() => {
    const messagesArray = []

    db.collection('messages').doc(chatID).collection('messages').get().then(snapshot => {
      snapshot.forEach(doc => messagesArray.push(doc.data()))
      setMessages(messagesArray)
    })
  }, [])


  useEffect(() => {
    // check if messages is not empty
    if(!messages.length) return

    const messageIDs = getIDs(messages) // your getIDs is not async, so no need to await
    db.collection('messages').doc(chatID).collection('messages').onSnapshot(doc => {
      doc.forEach((document) => {
        if (messageIDs.indexOf(document.data()._id) !== -1) {
          console.log('the is is ', messageIDs.indexOf(document.data()._id))
        } else {
          console.log('notfoundssw')
        }
      })
    })
}, [messages])

答案 1 :(得分:1)

我不确定我是否能完全理解您是如何获取数据的,但设置状态实际上是异步的,因此您无法保证在执行 map 时所有状态数据都已更新。

我会把你的 useEffect 分成两个不同的。

将包含 fetchMessages 调用的第二个调用应该使用 'messages' 作为其依赖数组的一部分,即它会在您的 'messages' 状态更新后执行。