将 useEffect 与异步一起使用?

Using useEffect with async?

我正在使用此代码:

useFocusEffect(
  useCallback(async () => {
    const user = JSON.parse(await AsyncStorage.getItem("user"));

    if (user.uid) {
      const dbRef = ref(dbDatabase, "/activity/" + user.uid);

      onValue(query(dbRef, limitToLast(20)), (snapshot) => {
        console.log(snapshot.val());
      });

      return () => {
        off(dbRef);
      };
    }
  }, [])
);

我收到此错误:

An effect function must not return anything besides a function, which is used for clean-up. It looks like you wrote 'useFocusEffect(async () => ...)' or returned a Promise. Instead, write the async function inside your effect and call it immediately.

我试图将所有内容都放在 async 函数中,但是 off() 没有被调用。

useEffect(() => {
const myFunction = async () => {
your code 
}
myFunction()
}, [])

在嵌套的 async 函数外部定义 dbRef 变量,以便您的清理回调可以引用它,并考虑到在清理发生时可能未设置它的可能性。

此外,无论何时在不处理函数 returns 承诺的地方使用 async 函数,请确保您不允许该函数抛出错误(return 一个被拒绝的承诺),因为没有任何东西可以处理那个被拒绝的承诺。

此外,由于组件可以在 await 期间卸载,您需要确保 async 函数在我们知道不会发生清理时不会继续其逻辑(因为它已经发生了),所以你可能需要一个标志(下面的didCleanup)。

所以像这样:

useFocusEffect(
    useCallback(() => {
        let dbRef;
        let didCleanup = false;
        (async() => {
            try {
                const user = JSON.parse(await AsyncStorage.getItem("user"));

                if (!didCleanup && user.uid) {
                    dbRef = ref(dbDatabase, "/activity/" + user.uid);

                    onValue(query(dbRef, limitToLast(20)), (snapshot) => {
                        console.log(snapshot.val());
                    });
                }
            } catch (error) {
                // ...handle/report the error...
            }
        })();
        return () => {
            didCleanup = true;
            if (dbRef) {
                off(dbRef);
            }
        };
    }, [])
);