如何在反应中删除新的 firebase onAuthStateChanged 侦听器
How to remove the new firebase onAuthStateChanged listener in react
我正在使用 react-router 在 React 网络应用程序中实施 firebase 身份验证。
用户使用 Facebook 或 Google 使用弹出式登录登录(在 /signin),然后如果成功,我将路由到主应用程序 (/)。在主应用程序组件中,我监听身份验证状态更改:
componentWillMount() {
this.authListener = this.authListener.bind(this);
this.authListener();
}
authListener 侦听身份验证更改:
authListener() {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
console.log('user changed..', user);
this.setState({
User: {
displayName: user.displayName
}
});
} else {
// No user is signed in.
browserHistory.push('/signin');
}
});
}
一切正常,除非我注销(并返回 /signin)并使用 facebook 或 google 再次登录。然后我收到一条错误消息:
Warning: setState(...): Can only update a mounted or mounting
component.
我怀疑来自现在卸载的先前登录状态应用程序的 onAuthStateChanged 侦听器仍然是 运行。
有没有办法在 App 组件卸载时删除 onAuthStateChanged 监听器?
您设置的任何侦听器也需要拆除。
你的怀疑非常切合实际。
您应该使用 componentWillUnmount 生命周期方法来删除任何可能污染您的应用程序的剩余侦听器。
清除监听器,相关代码如下:
在您的 authListener
函数中,您需要在组件中保存对侦听器的引用(调用 firebase.auth().onAuthStateChanged
后返回给您)。这将是一个钩子,它将取消引用侦听器并将其删除。
因此,与其调用它,不如将返回值原样保存
this.fireBaseListener = firebase.auth().onAuthStateChanged ...
当您的组件卸载时,使用此代码:
componentWillUnmount() {
this.fireBaseListener && this.fireBaseListener();
this.authListener = undefined;
}
@Justin 因为 onAuthStateChanged
returns 函数所以你可以用它来清除监听器...
this.fireBaseListener = firebase.auth().onAuthStateChanged
文档:https://firebase.google.com/docs/reference/js/firebase.auth.Auth#onAuthStateChanged
Returns non-null firebase.Promise containing non-null Array of string
您可以像这样检查订阅,而不是在 componentDidMount()
中检查 onAuthStateChanged()
函数。
componentWillMount() {
//following line will help you to setState() but not required
let set = this
//this is our trick
this.unsubscribe = firebase.auth().onAuthStateChanged(user => {
if (!user) {
//navigate to guest stack
//actually im using react-navigation
set.props.navigation.navigate('Guest');
} else {
//set current user to state
set.setState({
user: user,
loading: false
})
}
});
}
//What you have to do next is unsubscribe ;)
componentWillUnmount() {
this.unsubscribe();
}
我知道我来晚了,但这里有一个基于钩子的解决方案:
React.useEffect(() => {
const unsubscribe = firebase.auth().onAuthStateChanged((user) => { // detaching the listener
if (user) {
// ...your code to handle authenticated users.
} else {
// No user is signed in...code to handle unauthenticated users.
}
});
return () => unsubscribe(); // unsubscribing from the listener when the component is unmounting.
}, []);
如果您使用的是 Firebase 9,您应该注意调用函数的方式
onAuthStateChanged
第一种方式
import firebaseApp from 'path/to/your/firebase/app';
// you will need to do
const auth = getAuth(firebaseApp);
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(user => {
if (user) {
// user is signed in
} else {
// user is signed out
}
});
// unsubscribing from the listener when the component is unmounting.
return unsubscribe;
}, [])
第二种方式
import firebaseApp from 'path/to/your/firebase/app';
import { getAuth, onAuthStateChanged } from 'firebase/auth';
const auth = getAuth(firebaseApp);
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
...
});
// unsubscribing from the listener when the component is unmounting.
return unsubscribe;
}, [])
我正在使用 react-router 在 React 网络应用程序中实施 firebase 身份验证。
用户使用 Facebook 或 Google 使用弹出式登录登录(在 /signin),然后如果成功,我将路由到主应用程序 (/)。在主应用程序组件中,我监听身份验证状态更改:
componentWillMount() {
this.authListener = this.authListener.bind(this);
this.authListener();
}
authListener 侦听身份验证更改:
authListener() {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
console.log('user changed..', user);
this.setState({
User: {
displayName: user.displayName
}
});
} else {
// No user is signed in.
browserHistory.push('/signin');
}
});
}
一切正常,除非我注销(并返回 /signin)并使用 facebook 或 google 再次登录。然后我收到一条错误消息:
Warning: setState(...): Can only update a mounted or mounting component.
我怀疑来自现在卸载的先前登录状态应用程序的 onAuthStateChanged 侦听器仍然是 运行。
有没有办法在 App 组件卸载时删除 onAuthStateChanged 监听器?
您设置的任何侦听器也需要拆除。
你的怀疑非常切合实际。
您应该使用 componentWillUnmount 生命周期方法来删除任何可能污染您的应用程序的剩余侦听器。
清除监听器,相关代码如下:
在您的 authListener
函数中,您需要在组件中保存对侦听器的引用(调用 firebase.auth().onAuthStateChanged
后返回给您)。这将是一个钩子,它将取消引用侦听器并将其删除。
因此,与其调用它,不如将返回值原样保存
this.fireBaseListener = firebase.auth().onAuthStateChanged ...
当您的组件卸载时,使用此代码:
componentWillUnmount() {
this.fireBaseListener && this.fireBaseListener();
this.authListener = undefined;
}
@Justin 因为 onAuthStateChanged
returns 函数所以你可以用它来清除监听器...
this.fireBaseListener = firebase.auth().onAuthStateChanged
文档:https://firebase.google.com/docs/reference/js/firebase.auth.Auth#onAuthStateChanged
Returns non-null firebase.Promise containing non-null Array of string
您可以像这样检查订阅,而不是在 componentDidMount()
中检查 onAuthStateChanged()
函数。
componentWillMount() {
//following line will help you to setState() but not required
let set = this
//this is our trick
this.unsubscribe = firebase.auth().onAuthStateChanged(user => {
if (!user) {
//navigate to guest stack
//actually im using react-navigation
set.props.navigation.navigate('Guest');
} else {
//set current user to state
set.setState({
user: user,
loading: false
})
}
});
}
//What you have to do next is unsubscribe ;)
componentWillUnmount() {
this.unsubscribe();
}
我知道我来晚了,但这里有一个基于钩子的解决方案:
React.useEffect(() => {
const unsubscribe = firebase.auth().onAuthStateChanged((user) => { // detaching the listener
if (user) {
// ...your code to handle authenticated users.
} else {
// No user is signed in...code to handle unauthenticated users.
}
});
return () => unsubscribe(); // unsubscribing from the listener when the component is unmounting.
}, []);
如果您使用的是 Firebase 9,您应该注意调用函数的方式
onAuthStateChanged
第一种方式
import firebaseApp from 'path/to/your/firebase/app';
// you will need to do
const auth = getAuth(firebaseApp);
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(user => {
if (user) {
// user is signed in
} else {
// user is signed out
}
});
// unsubscribing from the listener when the component is unmounting.
return unsubscribe;
}, [])
第二种方式
import firebaseApp from 'path/to/your/firebase/app';
import { getAuth, onAuthStateChanged } from 'firebase/auth';
const auth = getAuth(firebaseApp);
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
...
});
// unsubscribing from the listener when the component is unmounting.
return unsubscribe;
}, [])