取消订阅 firestore(...).onSnapshot() 在涉及 dispatch() 时不起作用
Unsubscribe to firestore(...).onSnapshot() does not work when dispatch() is involved
主要目标:在注销用户之前正确取消订阅所有 firestore-listeners,防止泄漏。
涉及的库:react、react-native、redux、redux-thunk 和 react-native-firebase。
问题:取消订阅 firestore(...)。当涉及 dispatch() 时,onSnapshot() 不起作用。
我使用 onSnapshot 和 returns 我在用户注销时调用的调用程序组件的取消订阅函数获取数据。奇怪的是,UNSUBSCRIBE 仅在没有发出 dispath 时才有效...
我有一个组件 (component.js) 连接到 redux 存储并不断获取一些用户数据,如下所示:
componentDidMount() {
this.unsubscribe = this.props.userFetch(); // userFetch is an action creator in actions.js
}
在actions.js
import firestore from '@react-native-firebase/firestore';
import auth from '@react-native-firebase/auth';
export const userFetch = () => {
return dispatch => {
const unsubscribe = firestore()
.doc(`users/${auth().currentUser.uid}`)
.onSnapshot({
error: e => console.warn('ERROR IN FETCH: ', e),
next: SnapshotUser => {
console.log('User: ', SnapshotUser.data());
// Will dispatch action below
},
});
return unsubscribe;
};
};
注意之前的action creator中暂时没有DISPATCH
如果我在 component.js 中调用取消订阅,firestore onSnapshot 侦听器会正确取消订阅,如下所示:
onLogoutPressed = () => {
this.unsubscribe(); // <-- HERE it works (for the moment...)
auth()
.signOut()
.then(() => {
console.log('user has been signout');
})
.catch(error => {
console.log('Error: ',error);
});
};
现在,如果我想通过调度将获取的数据发送到 redux 存储,我会在 actions.js
中添加这样的调度
export const userFetch = () => {
return dispatch => {
const unsubscribe = firestore()
.doc(`users/${auth().currentUser.uid}`)
.onSnapshot({
error: e => console.warn('ERROR IN FETCH: ', e),
next: SnapshotUser => {
console.log('User: ', SnapshotUser.data());
// Will dispatch action below
dispatch({ // <--------------------------------- HERE
type: 'USER_FETCH_SUCCESS',
payload: SnapshotUser.data(),
});
},
});
return unsubscribe;
};
};
但突然在我的 component.js 中,this.unsubscribe 在注销时不再工作。
我发现那个人也在做同样的事情,但在 React 上为他工作:here。
其他人提供的解决方案基本上也是 。
由于 redux-thunk,firestore-onsnapshot-listener 似乎被包裹在一些调度调用中,我现在无法理解它的行为方式。
有人有解决办法吗?
好的,在 Reactiflux 上@ioss 的帮助下解决了这个问题。
由于一些奇怪的原因,componentDidMount 被挂载了两次,创建了多个监听器,因此卸载一个是不够的。
通过在 componentWillUnmount().
的 unsubscribe() 上添加另一个 运行 来解决它
主要目标:在注销用户之前正确取消订阅所有 firestore-listeners,防止泄漏。
涉及的库:react、react-native、redux、redux-thunk 和 react-native-firebase。
问题:取消订阅 firestore(...)。当涉及 dispatch() 时,onSnapshot() 不起作用。
我使用 onSnapshot 和 returns 我在用户注销时调用的调用程序组件的取消订阅函数获取数据。奇怪的是,UNSUBSCRIBE 仅在没有发出 dispath 时才有效...
我有一个组件 (component.js) 连接到 redux 存储并不断获取一些用户数据,如下所示:
componentDidMount() {
this.unsubscribe = this.props.userFetch(); // userFetch is an action creator in actions.js
}
在actions.js
import firestore from '@react-native-firebase/firestore';
import auth from '@react-native-firebase/auth';
export const userFetch = () => {
return dispatch => {
const unsubscribe = firestore()
.doc(`users/${auth().currentUser.uid}`)
.onSnapshot({
error: e => console.warn('ERROR IN FETCH: ', e),
next: SnapshotUser => {
console.log('User: ', SnapshotUser.data());
// Will dispatch action below
},
});
return unsubscribe;
};
};
注意之前的action creator中暂时没有DISPATCH
如果我在 component.js 中调用取消订阅,firestore onSnapshot 侦听器会正确取消订阅,如下所示:
onLogoutPressed = () => {
this.unsubscribe(); // <-- HERE it works (for the moment...)
auth()
.signOut()
.then(() => {
console.log('user has been signout');
})
.catch(error => {
console.log('Error: ',error);
});
};
现在,如果我想通过调度将获取的数据发送到 redux 存储,我会在 actions.js
中添加这样的调度export const userFetch = () => {
return dispatch => {
const unsubscribe = firestore()
.doc(`users/${auth().currentUser.uid}`)
.onSnapshot({
error: e => console.warn('ERROR IN FETCH: ', e),
next: SnapshotUser => {
console.log('User: ', SnapshotUser.data());
// Will dispatch action below
dispatch({ // <--------------------------------- HERE
type: 'USER_FETCH_SUCCESS',
payload: SnapshotUser.data(),
});
},
});
return unsubscribe;
};
};
但突然在我的 component.js 中,this.unsubscribe 在注销时不再工作。
我发现那个人也在做同样的事情,但在 React 上为他工作:here。
其他人提供的解决方案基本上也是
由于 redux-thunk,firestore-onsnapshot-listener 似乎被包裹在一些调度调用中,我现在无法理解它的行为方式。
有人有解决办法吗?
好的,在 Reactiflux 上@ioss 的帮助下解决了这个问题。 由于一些奇怪的原因,componentDidMount 被挂载了两次,创建了多个监听器,因此卸载一个是不够的。 通过在 componentWillUnmount().
的 unsubscribe() 上添加另一个 运行 来解决它