尝试获取用户的身份验证状态火力时响应本机 useEffect 渲染问题



我对useEffect有问题。当我试图在onAuthStateChanged之后获得用户的身份验证状态时,useEffect中的调用数量高得离谱。有时也会出现以下错误:

警告:无法对已卸载的组件执行React状态更新。这是一个非操作,但表示应用程序中存在内存泄漏。要修复此问题,请取消useEffect清理函数中的所有订阅和异步任务

这是用户登录/注册和注销后的日志量。也许我不太了解useEffect是如何工作的。以下是使用useEffect:的代码

useEffect(async () => {
let isCancelled = false;
await firebase.auth().onAuthStateChanged(async (user) => {
if (user && !isCancelled) {
await firebase
.firestore()
.collection('users')
.doc(user.uid)
.get()
.then((document) => {
const userData = document.data()
console.log(document.data())
setUser(userData);
setIsSignedIn(true);
setLoading(false);
})
.catch((error) => {
setLoading(false);
alert(error)
});
}else{
console.log('user does not exist')
setIsSignedIn(false);
setLoading(false);
}
});
return () => {
isCancelled = true;
}
}, []);

这是它的图像。也许更清晰

通常,每个useEffect应该负责一项任务。此外,当前使用isCancelled的方法实际上并没有像应该的那样清理侦听器。

对于react,您应该尽可能使用实时更新。您还将受益于能够轻松地分离侦听器。

这是一个脚手架,你可以在上面工作。

// Set up a state variable to contain the user's info
// If a user is already logged in and validated, user is immediately
// set to their User object, otherwise show loading icon while we check
const [user, setUser] = useState(() => firebase.auth().currentUser || undefined);
const userLoading = user === undefined;
const isSignedIn = !!user;
// Set up a state variable to contain the user's data
const [userData, setUserData] = useState(undefined);
// Set up a state variable to contain whether this component is loading
const [loading, setLoading] = useState(true);
// effect to track user state and update `user` for any changes
// onAuthStateChanged returns its own cleanup function
useEffect(() => firebase.auth().onAuthStateChanged(setUser), []); // <- don't rerun
// effect to navigate to login
useEffect(() => {
if (user === null) {
// user is signed out
navigation.navigate('login');
}
}, [user]); // <- rerun when user changes
useEffect(async () => {
if (!isSignedIn) return; // you could write this as `userLoading || !isSignedIn`, but it's redundant
return firebase.firestore()
.collection('users')
.doc(user.uid)
.onSnapshot({ // <- onSnapshot() returns its own cleanup function
next(docSnapshot) {
const userData = docSnapshot.data();
setUserData(userData);
},
error(err) {
console.error(err);
alert(err);
}
});
}, [user]); // <- rerun when user changes

作为一个学习项目,可以考虑将其制作成Context或创建自己的useAuth函数,在其中可以提取用户的数据、用户对象和加载状态。

试试这个

useEffect(async () => {
let isCancelled = false;
const unsubscribe = await firebase.auth().onAuthStateChanged(async (user) => {
........ 
});
return () => {
// cleanup 
unsubscribe() 
isCancelled = true;
}
}, []);

让我知道它是否适合你b

相关内容

  • 没有找到相关文章

最新更新