[英]How to correctly clean up function when fetching Firebase database() on()?
我收到以下错误。 我认为这是因为即使我的组件卸载,我仍然订阅了 Firebase 数据库。 我正在尝试利用实时功能,以便每当从列表中删除项目时,它都会反映在 UI 上。
我创建了多个具有单一目的的函数来获取不同的文档。 下面是一个例子。
export const getAllTask = (userId) => {
return new Promise((resolve, reject) => {
const db = database.ref('tasks');
db.child(`${userId}/taskItems`).on('value', (snapshot) => {
const user = snapshot.val();
if (user) {
resolve(user);
} else {
reject(user);
}
});
});
};
然后,无论何时我的任何组件,它都会运行我的 useEffect 来获取数据,但是当它卸载时,我如何正确使用off()
或正确清理? 有没有更好的方法来做到这一点?
useEffect(() => {
const test = async (userId) => {
await getAllTask(userId).then((result) => {
setItems(result);
});
};
test(userId);
}, [userId]);
试试这个,useEffect 返回一个在组件卸载时调用的函数
useEffect(() => {
let mounted=true;
const test = async (userId) => {
await getAllTask(userId).then((result) => {
if(mounted) setItems(result)
});
};
test(userId);
return ()=>{mounted=false}
}, [userId]);
在这种情况下,您根本不应该使用on()
。 使用once()
读取数据。 它返回一个易于使用的承诺。 on()
用于持久侦听器,每当查询结果发生变化时,这些侦听器都会随着时间的推移提供更新。
由于 Promise 只能解析一次,因此将持久侦听器包装在 Promise 中是没有意义的。
如果随着时间的推移做其实是想监听更新,只要组件安装,不承诺包裹。 相反,您应该通过返回一个它可以调用以关闭事物的函数来指示您的 useEffect 取消订阅侦听器。
另请参阅: 如何使用 Firebase 和 useEffect() 正确更新状态? 在那里的答案中,看看 useEffect 钩子如何返回一个调用off()
的函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.