Reactjs 针对多个功能的React useEffect清理
我有一个处理Firebase身份验证的useEffect。 当我注销然后再次登录时,我看到这个效果被调用了两次。每次我注销和重新登录时,都被称为额外时间 我觉得我需要用一个清理函数来处理这个问题,但我不知道如何编写它 这是我的钩子:Reactjs 针对多个功能的React useEffect清理,reactjs,firebase,firebase-authentication,react-hooks,Reactjs,Firebase,Firebase Authentication,React Hooks,我有一个处理Firebase身份验证的useEffect。 当我注销然后再次登录时,我看到这个效果被调用了两次。每次我注销和重新登录时,都被称为额外时间 我觉得我需要用一个清理函数来处理这个问题,但我不知道如何编写它 这是我的钩子: useEffect(() => { console.log('RUNNING THE EFFECT'); function routeUser(user) { // Redirect user somewhere depending on us
useEffect(() => {
console.log('RUNNING THE EFFECT');
function routeUser(user) {
// Redirect user somewhere depending on user state
}
function setupUser(user: User) {
// sets the user state object
routeUser(user);
}
if (!user) {
firebase.auth().onAuthStateChanged((authUser) => {
if (authenticatedUser) {
callGraphQLMethod({ variables: { uid: authUser.uid, phoneNumber: authUser.phoneNumber } })
.then(async (document) => {
setupUser(...);
});
}
});
} else {
// User object is already in state. use that instead
}
return () => {
// >>>>>>>> How do I clean all this up?
}
}, [callGraphQLMethod, setUser, user]);
很多时候,像这样的函数会返回一个cleanup函数来取消对资源的订阅。
onAuthStateChanged的情况似乎也是如此
如果在效果内部设置状态,则它将渲染,因为它有一个新的状态值,但效果未附加到每个用户状态。也就是说,为什么我越来越多地重播。如果我注销并返回100次,此效果将运行100次。这正常吗?每次效果运行时,您都在添加另一个onAuthStateChanged
回调。您可能只希望在安装组件时运行该部分效果一次。处理具有依赖性的效果中的其他函数。每次更改组件中的状态时,它将重新渲染,每次更改组件的道具时,它将重新渲染(当然,如果需要,在某些情况下,您可以使用React.memo部分停止此行为)但是,如果您正在加载一个组件,然后在装载时获取一个值并将其设置为状态,则reacts就是这样工作的,它将重新加载以向您显示它的结果normal@DrewReese那又是什么呢?这就是我需要清理的吗?太棒了。你能解释一下退订是做什么的吗。它与onAuthStateChanged函数的关系。我知道“?”是检查它是否存在,但什么是“()”?@Ben可选链接(?。
)运算符检查函数,即,您可以取消订阅(
)而不是取消订阅(
)。
onAuthStateChanged ( nextOrObserver : Observer < any > | ( ( a :
User | null ) => any ) , error ? : ( a : Error ) => any ,
completed ? : firebase.Unsubscribe ) : firebase.Unsubscribe
useEffect(() => {
let unsubscribe;
...
if (!user) {
unsubscribe = firebase.auth().onAuthStateChanged((authUser) => {
...
});
} else {
...
}
return () => {
unsubscribe?.();
}
}, [callGraphQLMethod, setUser, user]);