我目前正在尝试使用React钩子来转换React + Material UI + Firebase模板。目前,我正在尝试将App.js中的生命周期方法转换为useEffect为止,这就是我所拥有的
useEffect(() => {
setMounted(true)
const removeAuthStateChangedObserver = auth.onAuthStateChanged((user) => {
//* if there is no user...
if (!user) {
if (removeReferenceListener) {
removeReferenceListener()
}
if (mounted) {
setUser(null)
setUserData(null)
setSignedIn(false)
setReady(true)
}
return
}
const uid = user.uid
//* if there is no uid...
if (!uid) {
if (removeReferenceListener) {
removeReferenceListener()
}
if (mounted) {
setUser(null)
setUserData(null)
setSignedIn(false)
setReady(true)
}
return
}
const reference = firestore.collection('users').doc(uid)
//* if there is no reference...
if (!reference) {
if (this.removeReferenceListener) {
this.removeReferenceListener();
}
if (mounted) {
setUser(null)
setUserData(null)
setSignedIn(false)
setReady(true)
}
return
}
const removeReferenceListener = reference.onSnapshot((snapshot) => { //!ADDED CONST HERE INSTEAD OF THIS
if (!snapshot.exists) {
if (removeReferenceListener) {
removeReferenceListener();
}
if (mounted) {
setUser(null)
setUserData(null)
setSignedIn(false)
setReady(true)
}
return
}
const data = snapshot.data();
if (!data) {
if (removeReferenceListener) {
removeReferenceListener();
}
if (mounted) {
setUser(null)
setUserData(null)
setSignedIn(false)
setReady(true)
}
return
}
if (mounted) {
setUser(user)
setUserData(data)
setSignedIn(true)
setReady(true)
}
})
})
//!FOR THE componentWillUnmount
return () => {
if (removeAuthStateChangedObserver) {
removeAuthStateChangedObserver();
}
if (removeReferenceListener) {
removeReferenceListener();
}
setMounted(false);
}}, [mounted])
在这里,已经使用useState挂钩符号定义了我的变量,user,userData,signedIn,准备好了。我在使用ESlint时遇到一些错误,告诉我在方法检查之前放置声明,或者在componentWillUnmount的最终返回语句中未定义'removeReferenceListener'。
如果有人可以帮助我,这将非常重要,因为这是应用程序中注册用户最重要的方法之一。如果更有用,这是我已经拥有的link。谢谢
答案 0 :(得分:0)
我已经用一些注释格式化了您的代码
useEffect(() => {
const removeAuthStateChangedObserver = auth.onAuthStateChanged(
user => {
//* if there is no user...
if (!user) {
//why would you try to do this? This only runs on the first mount
// and you didn't create removeReferenceListener yet
// if (removeReferenceListener) {
// removeReferenceListener();
// }
//just set the state, App will never unmount
setUser(null);
setUserData(null);
setSignedIn(false);
setReady(true);
return;
}
const uid = user.uid;
//* if there is no uid...
if (!uid) {
//again trying to call removeReferenceListener when it wasn't created
// yet
// if (removeReferenceListener) {
// removeReferenceListener();
// }
setUser(null);
setUserData(null);
setSignedIn(false);
setReady(true);
return;
}
const reference = firestore
.collection('users')
.doc(uid);
//* if there is no reference...
if (!reference) {
//you still didn't create removeReferenceListener, why keep trying to
// call it?
// if (removeReferenceListener) {
// removeReferenceListener();
// }
setUser(null);
setUserData(null);
setSignedIn(false);
setReady(true);
return;
}
//now you finally create removeReferenceListener and you want to call this
// if App unmounts, but App never unmounts?
const removeReferenceListener = reference.onSnapshot(
snapshot => {
//!ADDED CONST HERE INSTEAD OF THIS
if (!snapshot.exists) {
if (removeReferenceListener) {
removeReferenceListener();
}
setUser(null);
setUserData(null);
setSignedIn(false);
setReady(true);
return;
}
const data = snapshot.data();
if (!data) {
if (removeReferenceListener) {
removeReferenceListener();
}
setUser(null);
setUserData(null);
setSignedIn(false);
setReady(true);
return;
}
setUser(user);
setUserData(data);
setSignedIn(true);
setReady(true);
}
);
}
);
//!FOR THE componentWillUnmount
// WHY? show me how the component will unmount
return () => {
if (removeAuthStateChangedObserver) {
removeAuthStateChangedObserver();
}
//removeReferenceListener is not even in scope here, you could put it in scope
// but why would you? Returning a cleanup function is pointless because
// App will only mount once and never unmount
// if (removeReferenceListener) {
// removeReferenceListener();
// }
};
}, []);