当前位置: 首页 > 知识库问答 >
问题:

带react-redux的Firestore分页

慕皓君
2023-03-14
const lastDocRef = firestoreDB.doc(`catalog/${publishedBooks.lastDocId}`)
const lastDoc = snap.docs[snap.docs.length-1];

我很感激任何帮助如何解决这个问题。

import { createSlice, createAsyncThunk, createEntityAdapter } from '@reduxjs/toolkit';
import firebaseService from 'app/services/firebaseService';

const firestoreDB = firebaseService.firestoreDB;

export const getPublishedBooks = createAsyncThunk('adminApp/publishedBooks/getPublishedBooks',
    async (params, { dispatch, getState }) => {
        const promise = firestoreDB
            .collection('catalog')
            .orderBy('lastPublish', 'desc')
            .limit(10)
            .get()
            .then(snap => {
                const lastDoc = snap.docs[snap.docs.length-1];
                dispatch(setLastDocId(lastDoc.id));
                let books = [];
                snap.forEach(bookDoc => {
                    const id = bookDoc.id;
                    const data = bookDoc.data();
                    const lastPublish = data.lastPublish.toDate().toISOString();
                    books.push({ ...data, id, lastPublish });
                });
                return books;
            })
            .catch(error => {
                return {}
            });

        const result = await promise;
        return result;
    }
);

export const getPublishedBooksNext = createAsyncThunk('adminApp/publishedBooks/getPublishedBooksNext',
    async (params, { dispatch, getState }) => {
        const { publishedBooks } = getState().adminApp;

        const lastDocRef = firestoreDB.doc(`catalog/${publishedBooks.lastDocId}`)

        const promise = firestoreDB
            .collection('catalog')
            .orderBy('lastPublish', 'desc')
            .startAfter(lastDocRef)
            .limit(10)
            .get()
            .then(snap => {
                const lastDoc = snap.docs[snap.docs.length-1];
                dispatch(setLastDocId(lastDoc.id));
                let books = [];
                snap.forEach(bookDoc => {
                    const id = bookDoc.id;
                    const data = bookDoc.data();
                    const lastPublish = data.lastPublish.toDate().toISOString();
                    books.push({ ...data, id, lastPublish });
                });
                return books;
            })
            .catch(error => {
                return {}
            });

        const result = await promise;
        return result;
    }
);

const publishedBooksAdapter = createEntityAdapter({});
const initialState = publishedBooksAdapter.getInitialState({
    lastDocId: null
});

export const {
    selectAll: selectPublishedBooks,
    selectById: selectPublishedBookById,
    selectTotal: selectPublishedBooksTotal
} = publishedBooksAdapter.getSelectors(state => state.adminApp.publishedBooks);

const publishedBooksSlice = createSlice({
    name: 'adminApp/publishedBooks',
    initialState,
    reducers: {
        resetPublishedBooks: (state, action) => initialState,
        setLastDocId: {
            prepare: doc => {
                const payload = doc
                return { payload };
            },
            reducer: (state, action) => {
                state.lastDocId = action.payload;
            }
        },
        resetLastDocId: {
            prepare: () => {
                const payload = null
                return { payload };
            },
            reducer: (state, action) => {
                state.lastDocId = action.payload;
            }
        },
    },
    extraReducers: {
        [getPublishedBooks.fulfilled]: publishedBooksAdapter.setAll,
        [getPublishedBooksNext.fulfilled]: publishedBooksAdapter.upsertMany
    }
});

export const { resetPublishedBooks, setLastDocId, resetLastDocId } = publishedBooksSlice.actions;

export default publishedBooksSlice.reducer;

共有1个答案

郎正初
2023-03-14

lastdocref只返回文档引用。你需要得到真正的医生本身。

const lastDocRef = await firestoreDB.doc(`catalog/${publishedBooks.lastDocId}`).get();

您应该使用await而不是then-catch来获得更易读的代码。

export const getPublishedBooksNext = createAsyncThunk('adminApp/publishedBooks/getPublishedBooksNext',
    async (params, { dispatch, getState }) => {
        const { publishedBooks } = getState().adminApp;

        try {
            const lastDocRef = await firestoreDB.doc(`catalog/${publishedBooks.lastDocId}`).get();

            const snap = await firestoreDB
                .collection('catalog')
                .orderBy('lastPublish', 'desc')
                .startAfter(lastDocRef)
                .limit(10)
                .get()
            
            const lastDoc = snap.docs[snap.docs.length-1];
            let books = [];
            dispatch(setLastDocId(lastDoc.id));
            snap.forEach(bookDoc => {
                const id = bookDoc.id;
                const data = bookDoc.data();
                const lastPublish = data.lastPublish.toDate().toISOString();
                books.push({ ...data, id, lastPublish });
            });

            return books;
        } catch (error) {
            return {}
        }
    }
);

编辑:您还可以保存lastdoc以redux,然后在以后引用它,以避免为lastdocref获取额外的工作负载。

export const getPublishedBooksNext = createAsyncThunk('adminApp/publishedBooks/getPublishedBooksNext',
    async (params, { dispatch, getState }) => {
        const { lastDocRef } = getState().adminApp; // get saved lastDoc 
    
        try {
            const snap = await firestoreDB
                .collection('catalog')
                .orderBy('lastPublish', 'desc')
                .startAfter(lastDocRef) // use it here. 
                .limit(10)
                .get()
            
            const lastDoc = snap.docs[snap.docs.length-1];
            let books = [];
            // dispatch(setLastDocId(lastDoc.id)); // instead of saving the doc id 
            dispatch(setLastDoc(lastDoc)); // save the last document instead 
            
            snap.forEach(bookDoc => {
                const id = bookDoc.id;
                const data = bookDoc.data();
                const lastPublish = data.lastPublish.toDate().toISOString();
                books.push({ ...data, id, lastPublish });
            });

            return books;
        } catch (error) {
            return {}
        }
    }
);
 类似资料:
  • 问题内容: 这是一个教育项目,不用于生产。我本来不想让用户登录。 我可以在没有用户登录的情况下使用CSRF令牌对Django进行POST调用吗?我可以不使用jQuery来做到这一点吗?我在这里不了解我的观点,并且肯定会混淆一些概念。 在JavaScript方面,我找到了这个redux-csrf软件包。我不确定如何将其与POST使用Axios的操作结合使用: 在Django方面,我已经阅读了有关CS

  • 目录 为何组件没有被重新渲染、或者 mapStateToProps 没有运行? 为何组件频繁的重新渲染? 怎样使 mapStateToProps 执行更快? 为何不在被连接的组件中使用 this.props.dispatch ? 应该只连接到顶层组件吗,或者可以在组件树中连接到不同组件吗? React Redux 为何组件没有被重新渲染、或者 mapStateToProps 没有运行? 目前来看,

  • Universal React Redux Boilerplate A universal React/Redux boilerplate with sensible defaults. Out of the box, thisboilerplate comes with: Server-side rendering with Express Code splitting with dynamic

  • React-Redux-Enterprise A React-Redux boilerplate for enterprise web applications. Before you start with this boilerplate, please take a few minutes to read this article and see if you really need this

  • Live redux-react-starter This repository contains the minimal app to get started with redux, react, hot-reloading, async function and some other great stuffs. How to yarn 0.18+ must be present on your

  • React/Redux Links Curated tutorial and resource links I've collected on React, Redux, ES6, and more, meant to be a collection of high-quality articles and resources for someone who wants to learn abou