从钩子状态对数组进行无限滚动反应

时间:2020-04-17 14:45:55

标签: reactjs react-infinite-scroll-component react-infinite-scroll

我在自己的React组件中设置react-infinite-scroller时遇到了麻烦。

我不想直接使用loadMore在我的组件中通过API获取数据,因为我已经从我的IndexedDB中获取了数据。

所以我想使用我的数组dbScans(带有对象的数组),并希望无限滚动以max为单位。数组的3个项目。

我试图创建一个loadProducts函数来切片和连接要渲染的数组,但是当我尝试在Infinite-Scroll组件中调用它时,出现了超载错误。

import React, { useEffect, useState } from 'react';
import InfiniteScroll from 'react-infinite-scroller';

export default function ProductHistory() {
  const [dbScans, setDbScans] = useState<IProductClient[]>([]);
  const [loadedProducts, setLoadedProducts] = useState([]);

  useEffect(() => {
    (async function getDataFromDB() {
      setDbScans(await db.yourScans.toArray());
    })();
  }, []);

  let productHistory = dbScans;

  // This function is not working
  const loadProducts = (page: number) => {
    const perPage = 3;
    const moreItems: any = dbScans.slice(
      page * perPage - perPage,
      page * perPage + 1
    );
    // Am I doing this right?
    setLoadedProducts(loadedProducts.concat(moreItems));
  }

  return (
    <>
      <div className="product-history">
          { productHistory.length > 0 ?

            <InfiniteScroll
              pageStart={0}
              loadMore={loadProducts(0)} // This is not working
              hasMore={true}
              loader={<div className="loader" key={0}>Loading ...</div>}
            >

              {productHistory.map((product: any) =>
                <div className="product-history__item" key={product.id}>
                  <p>{product.name}
                </div>
              )}

              </InfiniteScroll>
            : ''
          }
      </div>
    </>
  )
}

1 个答案:

答案 0 :(得分:2)

您应该引入一个名为lastObjectPosition的状态变量,该变量将具有无限滚动显示的最后一个对象的位置。

    const perPage = 3;
    const [lastObjectPosition , setLastObjectPosition ] = useState(0);

然后应将hasMore属性设置如下:

    hasMore={lastObjectPosition < dbScans.length}

最后,您应该像这样修改loadProducts函数,

    const loadProducts = () => {
        setLoadedProducts(currentProducts => {
            return [
                ...currentProducts,
                dbScans.slice(lastObjectPosition, lastObjectPosition+perPage)
            ]
        });
        setLastObjectPosition(currentValue => {
            return currentValue + perPage
        }
    }