我目前正在尝试使用React挂钩转换React+MaterialUI+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])
在这里,已经定义了我的变量user、userData、signedIn,准备使用useState钩子表示法。ESlint告诉我在方法检查之前放置声明,或者在componentWillUnmount的最终返回语句中没有定义"removeReferenceListener",我收到了一些错误。
如果有人能帮我一把,这将是非常重要的,因为这是应用程序中为用户注册的最重要的方法之一。这是我已经拥有的链接,如果它更有帮助的话。感谢
我已经用一些注释格式化了您的代码
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();
// }
};
}, []);