主要目标:在注销用户之前,正确取消订阅所有firestore侦听器,防止泄漏。
涉及的库:react、react native、redux、redux thunk和react nativefirebase
问题:取消订阅firestore(…(。当涉及dispatch((时,onSnapshot((不起作用
我使用onSnapshot获取数据,并将取消订阅函数返回给调用方组件,我在用户注销时调用该组件。奇怪的是,UNSUBSCRIBE只有在没有调度的情况下才有效。。。
我有一个组件(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;
};
};
请注意,在上一个动作创建者中暂时没有DISPATCH。
如果我在component.js中调用unsubscribe,firestoreonSnapshot侦听器将正确地取消订阅,如下所示:
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上为他工作:在这里。另一个人提供的解决方案也基本相同。
由于redux-thunk,firestoreonsnapshot侦听器似乎被包裹在某个调度调用中,我无法理解它现在的行为。
有人有解决方案吗?
Ok在Reactiveflux上的@ioss的帮助下解决了这个问题。由于一些奇怪的原因,组件DidMount被挂载了两次,创建了多个侦听器,因此仅仅卸载一个是不够的。通过在componentWillUnmount((中添加另一个unsubscribe((来解决此问题。