防止`useEffect`循环

时间:2020-09-04 01:05:39

标签: reactjs firebase-authentication react-hooks use-effect

我有一个简单的useEffect,我不确定如何停止无休止地调用。它会不断触发第一个if有条件的射击。我已经阅读了很多有关钩子的内容,并且我假设(可能是错误地)组件的每个渲染都会导致对我的useAuth()useUser()钩子的 new 调用。由于它们在内存中有新引用,因此会触发useEffect的deps,因为从技术上讲,这是此新组件渲染范围中存在的新函数?

至少这是我的想法,如果确实如此,不知道如何解决。

const RootPage = ({ Component, pageProps }): JSX.Element => {
  const { logoutUser } = useAuth();  // imported
  const { fetchUser } = useUser();   // imported
  const router = useRouter();

  useEffect(() => {
    // authStatus();
    const unsubscribe = firebaseAuth.onAuthStateChanged((user) => {
      if (user) {
        console.log(1);
        return fetchUser(user.uid); // async function that fetches from db and updates redux
      }
      console.log(2);
      return logoutUser(); // clears userData in redux
    });
    return () => unsubscribe();
  }, [fetchUser, logoutUser]);

  ...
}

fetchUser

  const fetchUser = async (uid) => {
    try {
      // find user doc with matching id
      const response = await firebaseFirestore
        .collection('users')
        .doc(uid)
        .get();
      const user = response.data();
      // update redux with user
      if (response) {
        return dispatch({
          type: FETCH_USER,
          payload: user,
        });
      }
      console.log('no user found');
    } catch (error) {
      console.error(error);
    }
  };

注销用户

  const logoutUser = async () => {
    try {
      // logout from firebase
      await firebaseAuth.signOut();
      // reset user state in redux
      resetUser();
      return;
    } catch (error) {
      console.error(error);
    }
  };

当我使用此useEffect刷新页面时,将输出到控制台:

enter image description here

1 个答案:

答案 0 :(得分:2)

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Hello
</body>
</html>

保持所有相同的内容,并用 useEffect(() => { function onAuthStateChange() { return firebaseAuth.onAuthStateChanged((user) => { if (user) { fetchUser(user.uid); } else { resetUser(); } }); } const unsubscribe = onAuthStateChange(); return () => { unsubscribe(); }; }, [fetchUser, resetUser]); 包裹fetchUserresetUser,此解决方案似乎正常工作。我目前还不确定为什么。