取消订阅 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() 上添加另一个 运行 来解决它