简单的 Auth 方法导致 "Maximum update depth exceeded"

Simple Auth method leads to "Maximum update depth exceeded"

我想使用 React 和 firebase 创建一个简单的身份验证。所以我的代码相当简单。我使用 firebase 身份验证来创建用户(非常有效)并获取用户(非常有效)。然后我将相应的令牌保存在 sessionStorage 中。 现在变得棘手了:我只想调用此令牌来检查用户是否有权访问页面。所以我的代码看起来像这样:

    function InternCheckPage() {

    let navigate = useNavigate();

    useEffect(() =>{
        let authToken = sessionStorage.getItem('auth_token')

        if(authToken){
            navigate('/intern')
        }
        if(!authToken){
            navigate('/login')
        }

    })

    return (
        <div className="App">
            <div className="App-header">
                <p>
                    InternCheck
                </p>
            </div>
        </div>
    );
}
export default InternCheckPage;

但是,这会导致以下错误:

Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.

我的页面停止响应。坦率地说,我不知道我做错了什么。我只是从教程中截取了这段代码,它应该可以正常工作。

有什么建议吗?

你真的不应该在没有依赖数组的情况下使用 useEffect,我认为在这种情况下,一个简单的空数组作为 useEffect 的第二个参数就可以解决问题。

useEffect(() => {
  ...code
}, []) 

意思是代码仅在第一次呈现组件时运行。

这是我使用过的另一种方法,可能会有帮助。您可以将这项工作委托给 firebase SDK 提供的 onAuthStateChanged 函数,而不是自己管理存储和检索经过身份验证的用户。

您在下面看到的是一个自定义挂钩,负责返回经过身份验证的用户。

import { useEffect, useRef, useState } from 'react';

import { getAuth, onAuthStateChanged, User } from '@firebase/auth';

import { app } from '../../configuration/FirebaseConfiguration';

const useAuth = () => {
  const [user, setUser] = useState<User | null>(null);
  const auth = getAuth(app);

  let mounted = useRef<boolean>(false);

  useEffect(() => {
    mounted.current = true;
    const unsubscribe = onAuthStateChanged(auth, (user) => {
      console.log("onAuthUserChanged", user);
      if (user) {
        if (mounted.current) {
          setUser(user);
        }
      } else {
        if (mounted.current) {
          setUser(null);
        }
      }
    });

    return () => {
      mounted.current = false;
      unsubscribe();
    };
  }, [auth]);

  return {
    user,
    auth,
  };
};

export { useAuth };

您可以在任何其他组件中这样调用它

 const { user } = useAuth();

而且,这是我使用这种方法创建的 github 存储库 https://github.com/SangeetAgarwal/FirebaseAuthReactRouterv6

这是我在学习 firebase 身份验证时发现非常有用的资源 link https://firebase.google.com/docs/web/setup

所以,现在使用上面的自定义身份验证挂钩,您的特定代码将如下所示

function InternCheckPage() {

    let navigate = useNavigate();
    
    const { user } = useAuth();

    useEffect(() => {
        // let authToken = sessionStorage.getItem('auth_token')

        if (user) {
            navigate('/intern')
        } else {
            navigate('/login')
        }
        //if(!authToken){
        //    navigate('/login')
        //}

    }, [user])

    return (
        <div className="App">
            <div className="App-header">
                <p>
                    InternCheck
                </p>
            </div>
        </div>
    );
}

export default InternCheckPage;

尝试使用此代码:

import React, { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';

export default function Test_1() {
let navigate = useNavigate();

useEffect(() => {
let authToken = sessionStorage.getItem('auth_token');

if (authToken) {
  navigate('/intern');
} else {
  navigate('/login');
}
}, []);

return (
<div className='App'>
  <div className='App-header'>
    <p>InternCheck</p>
  </div>
</div>
);
}

由于修复了错误,我稍微更改了您的代码。这有望在现在起作用。