我有一个“帖子”,它会像这样监听react
中其注释的更改:
// React hook state
const [comments, setComments] = useState([])
// My listener in useEffect
db.collection(`users/${userId}/posts/${postId}/comments`)
.onSnapshot((querySnapshot) => {
let newComments = []
querySnapshot.forEach(function (doc) {
newComments.push({
id: doc.id,
...doc.data()
})
})
setComments(newComments)
})
当用户创建新评论时,我会设置加载状态并禁用评论部分
// React hook
const [isLoading, setLoading] = useState(false)
// Add comment
const addComment = () => {
const comment = {text:"hello"}
setSaving(true)
db.collection(`users/${postUid}/posts/${postId}/comments`).doc()
.set(comment)
.then(()=>{
setSaving(false)
})
}
我的问题是(要解决的一个好问题),在我的onSnapshot
回调完成之前,订阅addComment
得到了新的注释,这产生了一些视觉问题:
-当评论输入仍在加载但评论已经存在时,使应用看起来有问题
-如果出现错误(例如:数据库权限问题),该注释将显示在列表中,然后消失...
您知道我可以更改什么才能在创建完成之前不进行onSnapshot
更新吗?
答案 0 :(得分:1)
如文档中的here所述:
应用程序中的本地写入将立即调用快照侦听器。 这是由于称为“延迟补偿”的重要功能。 当您执行写操作时,您的听众将收到新的通知 数据发送到后端之前。
检索到的文档具有
metadata.hasPendingWrites
属性,该属性可以 指示文档是否具有尚未进行的本地更改 尚未写入后端。
另请参见“收听集合中的多个文档” section中的以下备注:
如上文在本地更改事件中所述,您将收到 事件立即为您的本地写入。您的听众可以使用 每个文档上的
metadata.hasPendingWrites
字段,以确定是否 该文档具有尚未写入本地的更改 后端。
因此,只有在将更改写入后端时,才可以使用此属性显示更改,该更改类似于以下几行(未经测试):
db.collection(`users/${userId}/posts/${postId}/comments`)
.onSnapshot((querySnapshot) => {
let newComments = []
querySnapshot.forEach(function (doc) {
if (!doc.metadata.hasPendingWrites) {
newComments.push({
id: doc.id,
...doc.data()
})
}
})
setComments(newComments)
})