加载React应用时如何设置运行的Firebase auth onAuthStateChanged()侦听器运行?

时间:2019-06-14 11:08:42

标签: javascript reactjs firebase firebase-authentication

我正在尝试在顶级组件let regEx = /^[a-zA-Z0-9]+-[a-zA-Z0-9]+-[a-zA-Z0-9]+/ let str1 = "5" let str2 = "df-df-01" let solutions = [str1,str2].filter(x => regEx.test(x)) // or .filter(/./.test.bind(regEx)) to make your teammates hate you console.log(solutions)上设置 Firebase身份侦听器,以便通过React上下文向所有其他组件提供App对象。 / p>

我目前正在这样做:

authUser

但是我得到了日志输出:

function App() {
  console.log('Rendering App...');
  const [authUser,setAuthUser] = useState(null);
  const [authWasListened,setAuthWasListened] = useState(false);

  useEffect(()=>{
    console.log('Running App useEffect...');
    const authListener = firebase.auth().onAuthStateChanged(
      (authUser) => {

        console.log(authUser);
        console.log(authUser.uid);

        if(authUser) {
          setAuthUser(authUser);
          setAuthWasListened(true);
        } else {
          setAuthUser(null);
          setAuthWasListened(true);
        }

      }
    );
    return authListener();

  },[]);

  return(
    authWasListened ?
    <Layout/>
    : <div>Waiting for auth...</div>
  );

}

似乎我正在设置侦听器,但它最初并未运行,因此它没有获得当前的身份验证状态(为空,因为我什至没有登录表单)。似乎正在等待更改发生。

Rendering App... Running App useEffect... 首先不是要获得当前的authListener状态,然后再听变化吗?我在做什么错了?

更新

我发现我做错了什么。 authUser应该返回一个函数来清除useEffect上的侦听器,而不是函数调用,就像我上面试图做的那样。因此,我的听众从未设置过。

这正在按预期进行:

unmount

2 个答案:

答案 0 :(得分:1)

请参见https://reactjs.org/docs/hooks-effect.html#example-using-hooks-1

  

为什么我们从效果中返回一个函数?这是用于效果的可选清理机制。每种效果都可能返回一个在其后清除的函数。这使我们可以保持彼此之间添加和删除订阅的逻辑。它们具有相同的作用!

     

React何时确切地清除效果?卸载组件时,React执行清理。但是,正如我们之前所了解的,效果会在每个渲染中运行,而不仅仅是一次。这就是为什么React在下一次运行效果之前还要清除先前渲染中的效果的原因。我们将在下面稍后讨论为什么这有助于避免错误以及如何选择退出此行为,以防它造成性能问题。

然后查看Set an authentication state observer and get user data

尝试以下代码。

function App() {
  console.log('Rendering App...');
  const [authUser,setAuthUser] = useState(null);
  const [authWasListened,setAuthWasListened] = useState(false);

  useEffect(()=>{
    console.log('Running App useEffect...');
    firebase.auth().onAuthStateChanged(
      (authUser) => {

        console.log(authUser);
        console.log(authUser.uid);

        if(authUser) {
          setAuthUser(authUser);
          setAuthWasListened(true);
        } else {
          setAuthUser(null);
          setAuthWasListened(true);
        }

      }
    );
  },[]);

  return(
    authWasListened ?
    <Layout/>
    : <div>Waiting for auth...</div>
  );

}

答案 1 :(得分:1)

监听器不是立即的。从首次加载页面开始,状态更改可能需要一些时间。如果要立即检查用户是否已登录,可以使用currentUser,但是再次更新可能需要一些时间,因此侦听器是更好的选择。