简体   繁体   English

获取 Firebase database() on() 时如何正确清理函数?

[英]How to correctly clean up function when fetching Firebase database() on()?

I am getting the error below.我收到以下错误。 I assume this is because I'm still subscribed to the Firebase database even when my component unmounts.我认为这是因为即使我的组件卸载,我仍然订阅了 Firebase 数据库。 I am trying to take advantage of the real-time features so that whenever an item is deleted from the list it will reflect on the UI.我正在尝试利用实时功能,以便每当从列表中删除项目时,它都会反映在 UI 上。

在此处输入图片说明

I have created multiple functions with a single purpose to fetch different documents.我创建了多个具有单一目的的函数来获取不同的文档。 Below is one example.下面是一个例子。

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);
      }
    });
  });
};

Then whenever any of my components, it runs my useEffect to fetch data however when it unmounts how can I correctly use off() or clean up correctly?然后,无论何时我的任何组件,它都会运行我的 useEffect 来获取数据,但是当它卸载时,我如何正确使用off()或正确清理? Is there a better approach to do this?有没有更好的方法来做到这一点?

useEffect(() => {
  const test = async (userId) => {
    await getAllTask(userId).then((result) => {
      setItems(result);
    });
  };
  test(userId);
}, [userId]);

try this ,useEffect returns a function that is called when component unmounts试试这个,useEffect 返回一个在组件卸载时调用的函数

useEffect(() => {
     let mounted=true;
    const test = async (userId) => {
       await getAllTask(userId).then((result) => {
         if(mounted) setItems(result)
      });
    };
   test(userId);
   return ()=>{mounted=false}
  }, [userId]);

In this case, you shouldn't use on() at all.在这种情况下,您根本不应该使用on() Use once() for reading data a single time .使用once() 读取数据 It returns a promise that's easy to work with.它返回一个易于使用的承诺。 on() is for persistent listeners that deliver updates over time every time something changes with the results of the query. on()用于持久侦听器,每当查询结果发生变化时,这些侦听器都会随着时间的推移提供更新。

Since promises can only resolve a single time, it doesn't make sense to wrap a persistent listener in a promise.由于 Promise 只能解析一次,因此将持久侦听器包装在 Promise 中是没有意义的。

If you do actually want listener updates over time, for as long as the component is mounted, don't wrap it in a promise.如果随着时间的推移其实是想监听更新,只要组件安装,不承诺包裹。 instead, you should instruct your useEffect to unsubscribe the listener by returning a function that it can invoke to shut things down.相反,您应该通过返回一个它可以调用以关闭事物的函数来指示您的 useEffect 取消订阅侦听器。

See also: How to properly update state with Firebase and useEffect()?另请参阅: 如何使用 Firebase 和 useEffect() 正确更新状态? In the answer there, see how the useEffect hook returns a function that calls off() .在那里的答案中,看看 useEffect 钩子如何返回一个调用off()的函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM