简单的 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>
);
}
由于修复了错误,我稍微更改了您的代码。这有望在现在起作用。
我想使用 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>
);
}
由于修复了错误,我稍微更改了您的代码。这有望在现在起作用。