如何使用 React Native Firebase 包克服 useEffect 运行多次的问题?

问题描述 投票:0回答:1

我正在尝试使用 React Native Firebase 构建一个简单的 android 应用程序,用于监听 onAuthStateChanged 的身份验证。如果我理解正确的话,onAuthStateChanged 方法有多个状态,所以它会多次触发 useEffect。问题是我想在身份验证后触发一个函数,检查用户是否包含在 firebase 数据库中,但由于这个原因,该函数将被多次触发,并且当我在onAuthStateChanged 函数。

    const [userDetails, setUserDetails] = useState();
    const [initializing, setInitializing] = useState(true);

     function onAuthStateChanged(user) {
        if (user !== null) {
          setUserDetails({
            name: user.displayName,
            email: user.email,
            photo: user.photoURL,
            theme: 'default',
          });
          if (initializing) setInitializing(false); 
          checkUserInDB()
        } else {
          setUserDetails(null);
          setInitializing(true);
        }
      }

  useEffect(() => {
    const subscriber = auth().onAuthStateChanged(onAuthStateChanged);
    return subscriber; // unsubscribe on unmount
  }, []);

为了克服这个问题,我可以调用 checkUserInDb() 函数,方法是将它留在 onAuthStateChanged 之外,等待 userDetails 并完成初始化状态:

if (userDetails !== null && initializing === false) {
        checkUserInDb()

虽然这将返回 userDetails,但如果我记录它,它会发生 3 次。我试图从几个角度(等待/然后/超时)解决它,但问题出在 useEffect 中,我只是没有想法。如果你能指出正确的方向,我将不胜感激。

react-native react-native-firebase
1个回答
0
投票

我花了几个小时弄清楚这个问题,我成功地克服了它。我相信

onAuthStateChanged
不喜欢我尝试使用上面的 userDetails 设置自定义状态。通过像文档中那样使用用户,我没有返回 undefined 。但它仍然不是问题的解决方案,因为它确实会在 onAuthStateChanged 解决之前运行 2-3 次。我发现了另一个 thread,其中有人使用了我实现的去抖动,并且对我的原始逻辑进行了一些重构,它开始工作了。

  var debounceTimeout;
  const DebounceDueTime = 200; // 200ms

  function onAuthStateChanged(user) {
    if (debounceTimeout) clearTimeout(debounceTimeout);
    debounceTimeout = setTimeout(() => {
      debounceTimeout = null;
      handleAuthStateChanged(user);
    }, DebounceDueTime);
  }

  function handleAuthStateChanged(user) {
    setUser(user);
    if (initializing) setInitializing(false);
    if (user !== null) {
      console.log('=========> User is authenticated already:', user);
      checkUserInDb(user);
    } else {
      console.log('=========> User not found or signed out:', user);
    }
  }

useEffect(() => {
    const subscriber = auth().onAuthStateChanged(onAuthStateChanged);
    return subscriber; // unsubscribe on unmount
  }, []);
© www.soinside.com 2019 - 2024. All rights reserved.