正如标题所说。我正在为我的聊天服务使用 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 错误行为
答案 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' 状态更新后执行。