【问题标题】:How to detach firestore listener in Redux Action如何在 Redux Action 中分离 firestore 监听器
【发布时间】:2020-01-28 15:46:51
【问题描述】:

我正在使用 Redux+Firestore 来获取数据并填充我的商店。我正在使用.onSnapshot 来收听给定集合中的数据。我不能做的是在我完成后分离监听器。

我已阅读 Firestore 文档并了解,为了分离侦听器,您需要将回调 (.onSnapshot) 存储为变量,然后调用该变量进行分离。

我面临的问题是我正在使用 Redux(并分别在 componentDidMount/componentWillUnmount 中附加/分离)。

我看到一个使用see here(尽管在 Vue 中)的模式,其中回调存储在本地数据变量中,所以我尝试将回调本身分派到 Redux 存储但它没有收到它。

代码如下:

注意:我已经尝试根据上面共享的链接在getRoomActivity 中添加真/假布尔值作为参数来调用unlisten(),此时我不知所措。

// group.js (redux action file)
export const getRoomActivity = (roomId) => (dispatch) => {
  const unlisten = roomCollection
    .where('room', '==', roomId)
    .onSnapshot((querySnapshot) => {
    const roomItems = [];
    querySnapshot.forEach((doc) => {
        roomItems.push(doc.data());
    });
  dispatch({ type: GET_ROOM_ACTIVITY, payload: roomItems });
  });
};

//Room.js (component)
componentDidMount() {
    this.props.getRoomActivity(this.props.roomId);
  }

  componentWillUnmount() {
    this.props.getRoomActivity(this.props.roomId);
  }

【问题讨论】:

  • 声明监听器时为什么要使用awaitonSnapshot() 不返回 Promise 而是返回函数,请参阅 firebase.google.com/docs/reference/js/…。我不知道 Redux,但是当你想分离监听器时,你必须调用 onSnapshot() 方法返回的这个函数。正如您在所引用的答案中所看到的,在 Vue.js 中,我们将此函数存储在一个变量中,并在必要时调用它。我们会在“纯”JavaScript 中做同样的事情,我想你应该能够在 Redux 中做同样的事情。
  • Re: async - 没有正确理解onSnapshot()。我试图在componentWillUnmount 中调用unlisten 但我认为它没有在同一个侦听器上调用该函数,因为正在侦听对相关集合的任何更改(根据console.log)
  • 你不能这样做:const unlisten = roomCollection .where('room', '==', roomId) .onSnapshot((querySnapshot) => {...}); componentWillUnmount(){ this.unlisten(); }?。再说一次,我一点也不精通 Redux,只是尝试一下......

标签: reactjs firebase google-cloud-firestore react-redux


【解决方案1】:

当您使用带有 dispatch() 的 thunk 时,thunk 返回的值将向上传递。

例如

function delayedHello(dispatch) {
  setTimeout(() => dispatch({type:'delayed-hello', payload:'hello'}), 1000);
  return '1s';
}

let val = dispatch(delayedHello);
console.log(val) // logs '1s'

所以我们可以将同样的特性应用到您从 getRoomActivity(someRoom) 返回的 thunk 上,以便将 onSnapshot 的取消订阅函数传递回调用者。

// group.js (redux action file)
export const getRoomActivity = (roomId) => (dispatch) => {
  return roomCollection // CHANGED: Returned the unsubscribe function
    .where('room', '==', roomId)
    .onSnapshot((querySnapshot) => {
      const roomItems = [];
      querySnapshot.forEach((doc) => {
          roomItems.push(doc.data());
      });
      dispatch({ type: GET_ROOM_ACTIVITY, payload: roomItems });
    });
};

//Room.js (component)
componentDidMount() {
  this.unsubscribe = dispatch(this.props.getRoomActivity(this.props.roomId));
}

componentWillUnmount() {
  this.unsubscribe();
}

【讨论】:

    猜你喜欢
    • 2018-03-27
    • 2021-01-12
    • 1970-01-01
    • 2021-07-12
    • 2018-11-15
    • 2017-11-28
    • 1970-01-01
    • 2018-10-25
    • 1970-01-01
    相关资源
    最近更新 更多