Firestore startAt()和Redux可序列化与不可序列化问题

huwehgph  于 2023-02-12  发布在  其他
关注(0)|答案(1)|浏览(145)

我的Firebase项目正处于十字路口,需要一些一般性的指导。以下是我从研究中了解到的事实:

  • Firestore查询有一个方便的分页功能(startAt / startAfter
  • 为了简单起见,startAt可以接受返回的记录,而不是根据查询的orderBy手动传递属性值。我更喜欢使用它(因此在StackOverflow上有这个问题)。
  • Redux工具包has a best practice指出状态中不允许存在不可序列化的对象。
  • QueryDocumentSnapshot(从Firestore查询返回)对象是不可序列化的,但是调用.data()会生成一个可序列化的JS对象。

这让我很为难,因为我需要在状态中存储一些可序列化的东西,以使RTK满意。但我需要为Firestore查询传递不可序列化的QueryDocumentSnapshot,以便它实际返回结果。(传递.data()的结果在我的测试中不起作用)。
我想知道是否有很多人不使用Redux w/ Firestore,因此没有遇到这个问题,因为普通的React useState钩子不会抱怨您的值是否可序列化。
有人有什么建议吗?我可以直接向startAt传递值,但我更喜欢传递最初返回的对象。
一些伪示例代码,从我的代码库中的几个文件中提取:

// gets constructed dynamically, but for illustration, some sample pipeline entries
const pipeline = [
  where('... etc'),
  orderBy('fieldABC'),
  limit(20),
];
const collRef = collection(db, collectionName);
const baseQuery = query(collRef, ...pipeline);

// put in state (1 of 2 ways)
const items = await getDocs(query); // RTK warning about non-serializable
// const items = (await getDocs(query)).map((doc) => doc.data()); // works, but breaks pagination if I pass one of these items to startAt

// later, due to "infinite scroll" want to get another set of records
// if lastItem is a QueryDocumentSnapshot, it works
const lastItem = items[items.length - 1];
const nextPageQuery = query(collRef, ...pipeline, startAt(lastItem);
klr1opcd

klr1opcd1#

一个与RTK团队的“强烈建议”相悖的简单解决方案(但如果您不与某些RTK边缘情况(如利用持久性)发生冲突,则可能值得这样做)是忽略不可序列化的值:

export const store = configureStore({
  reducer: {
    // ...
  },
  middleware: (getDefaultMiddleware) => {
    const ware = getDefaultMiddleware({
      serializableCheck: {
        ignoreState: true,
      },
    });
    return ware.concat(firebaseApi.middleware);
  },
});

对于我的用例来说,这是一个足够好的黑客,但可能不能完全解决其他人的问题。

相关问题