简体   繁体   中英

React - Cloud FireStore - How can I add pagination to this component?

I'm trying to add a simple pagination for this React component.

First I run a query to find out the total number of documents in the collection. Next, inside useEffect, I run a second query to show the data. Ideally it should show 10 documents on each page.

import React, { useState, useEffect } from 'react';
import { db } from '../firebase';
import UpdateCard from './UpdateCard';

const List = () => {
  const [cards, setCards] = useState([]);
  const [beginAfter, setBeginAfter] = useState(0);
  const [totalDoclNumbers, setTotalDoclNumbers] = useState(0);

  const docLimit = 10;

  const firstFetch = async () => {
    const data = await db
      .collection('FlashCards')
      .get();
    setTotalDoclNumbers(data.docs.length);
    console.log('totalDoclNumbers is: ' + totalDoclNumbers);
  };

  firstFetch();

  useEffect(() => {
    const fetchData = async () => {
      const data = await db
        .collection('FlashCards')
        .orderBy('customId', 'asc')
        .limit(docLimit)
        .startAfter(beginAfter)
        .get();
      setCards(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));

    };
    fetchData();
  }, [beginAfter]);

  // Creating a menu for our documents (100 documents per each menu)
  const RenderDocumentMenu = () =>
    Array(totalDoclNumbers / docLimit)
      .fill()
      .map((_, i) => {
        const onClick = () => setBeginAfter(docLimit * i);
        return (
          <div key={i} className='document__set' onClick={onClick}>
            {docLimit * i + 1} to {docLimit * i + docLimit} Data
          </div>
        );
      });

  return (
    <>
      <div className='document'>
        <RenderDocumentMenu />
      </div>

      <ul className='list'>
        {cards.map((card) => (
          <li key={card.id} className='list__item'>
            <UpdateCard card={card} />
            <DeleteCard card={card} />
          </li>
        ))}
      </ul>
      <AddCard />
    </>
  );
};

export default List;

But when I run the code I get this error: RangeError: Invalid array length On the following line: const RenderDocumentMenu = () =>

OMG,. I found the problem and could fix it. It turned out that the number of documents in the collection was 58 .

totalDoclNumbers is 58

docLimit is 10

Hence the result of: Array(totalDoclNumbers / docLimit) is 5.8

And JS didn't know what to do with 5.8. As it should be the number of links that it has to generate for pagination.

The solution was rounding up the number (to 6 in this case):

Array(Math.ceil(totalDoclNumbers / docLimit))

I could use Math.round, but then if we had only let's say 54 documents in our collection, which would be rounded up to only 5 links, our solution would have ignored the last 4 documents.

Therefor to cover those cases, I'm using Math.ceil to round our number upward to its nearest integer.

Now the pagination is working, but I'm not sure if this is the best way to accomplish it.

Would appreciate any recommendation or improved solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM