【问题标题】:Unsubscribe to firestore(...).onSnapshot() does not work when dispatch() is involved当涉及 dispatch() 时,取消订阅 firestore(...).onSnapshot() 不起作用
【发布时间】:2020-07-27 19:57:45
【问题描述】:

主要目标:在注销用户之前正确取消订阅所有 firestore-listeners,防止泄漏。

涉及的库:react、react-native、redux、redux-thunk 和 react-native-firebase。

问题:在涉及 dispatch() 时,取消订阅 firestore(...).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,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。 这个其他人提供的解决方案基本上也是same

由于 redux-thunk,firestore-onsnapshot-listener 似乎被包裹在一些调度调用中,我现在无法理解它的行为。

有人有解决办法吗?

【问题讨论】:

    标签: reactjs react-native react-redux redux-thunk react-native-firebase


    【解决方案1】:

    好的,在@ioss on Reactiflux 的帮助下解决了这个问题。 由于一些奇怪的原因,componentDidMount 被挂载了两次,创建了多个监听器,因此卸载一个是不够的。 通过在 componentWillUnmount() 中的 unsubscribe() 上添加另一个运行来解决它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多