【问题标题】:Lookup multiple Firebase entries using Redux action使用 Redux 操作查找多个 Firebase 条目
【发布时间】:2020-01-31 01:28:57
【问题描述】:

我有这个 Redux 操作,它查找用户并返回他们拥有的所有项目:

export const itemsFetch = () => {
  const { currentUser } = firebase.auth();
  return dispatch => {
    firebase
      .database()
      .ref(`users/${currentUser.uid}/items`)
      .on('value', snapshot => {
        dispatch({ type: ITEMS_FETCH_SUCCESS, payload: snapshot.val() });
      });
  };
};

效果很好,返回的每个项目都有一个与之关联的唯一键。

我想修改此操作以查找特定项目,我已经完成了。这也很好用:

export const itemLookup = uid => {
  const { currentUser } = firebase.auth();
  return dispatch => {
    firebase
      .database()
      .ref(`users/${currentUser.uid}/items/${uid}`)
      .on('value', snapshot => {
        dispatch({ type: ITEM_LOOKUP_SUCCESS, payload: snapshot.val() });
      });
  };
};

这也很好用,但我只能用它来查找单个项目。

我想遍历一组项目 ID,并查找每个项目的详细信息。从组件执行此操作并使用 mapStateToProps 会导致组件每次重新呈现,从而丢失进程中的先前查找。

最好在组件级别遍历我拥有的 id,并进行多次调用。或者我应该将数组传递给动作,并以某种方式在动作中循环它们?

谢谢

我觉得我在做一些愚蠢的事情,或者完全误解了 Redux。

【问题讨论】:

  • 我认为你应该更新你的 reducer 以期待两个动作,一个说我开始查找一个新的 ID 列表,这应该清除当前列表。每次 API 请求返回时,应该分派另一个操作,reducer 获取该值并将其添加到当前列表中。
  • 谢谢 - 我认为这是有道理的。您能否提供一个简短示例,说明如何在该 reducer 中构建结果数组?目前它只返回 action.payload
  • case GET_VALUE_SUCCESS: return { ...state, myArray: [...state.myArray, action.newValue] } 类似的东西,或者你喜欢做数组连接/合并

标签: reactjs firebase react-native firebase-realtime-database react-redux


【解决方案1】:

在我看来,这是 Firebase 的少数限制之一(与查询一起),有时让我想再次长出头发并失去它(我秃头)。

虽然我使用过数据库,但我对 Firestore 的经验更丰富,但我认为你是正确的,你只能在 Firebase 中请求一项。为了解决这个问题,我要做的是创建一个新操作,它接收一组 ID,然后执行查询每个文档的 Promise 数组。

类似的东西(伪代码,你可能需要将你的 firebase 调用包装成一个 Promise):

let promises = [];
arrayIds.forEach(id => {
   promises.push(firebase.database().ref.get(id))
})
return Promise.all(promises).then(dispatch(results))

现在,如果您发现结果的数量通常不是很多,那么在客户端完成数据过滤是完全可以的(通常是 Firebase 要求的方式)。

【讨论】:

  • 感谢您的出色回答。我设法通过以下方式解决了我的问题 - 受到您的伪代码的启发。我将发布一个单独的答案以获得更好的格式。
【解决方案2】:

使用 sfratini 的回复,我设法解决了这个问题。操作如下:

export const itemLookup = oid => {
  const { currentUser } = firebase.auth();

  const items = []

  return dispatch => {
    new Promise(function (res, rej) {
      oid.forEach(id => {
        firebase.database().ref(`users/${currentUser.uid}/items/${id}`).on('value', snapshot => {
          items.push(snapshot.val())
        })
      })

    }).then(dispatch({ type: ITEM_LOOKUP_SUCCESS, payload: items }))
  }

我使用了相同的 reducer,现在 items 数组将其降为组件级别。完美!

【讨论】:

    猜你喜欢
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    • 2017-12-04
    • 2021-07-09
    • 2018-11-25
    • 1970-01-01
    相关资源
    最近更新 更多