首页 > 解决方案 > 在 nextjs 上处理延迟加载数据列表

问题描述

以前,我曾经一次调用所有数据。现在我有很多数据,我想到了使用延迟加载的概念。但我无法按照我想要的方式实现它。

当前的工作场景是,我将首先仅获取 6 个项目,当用户单击加载更多按钮时,将获取更多 6 个项目,但问题是它获取 12 个项目,而不是仅获取 6 个附加项目。

预期的最初是仅获取 6 个项目。现在,当用户单击加载更多按钮时,只获取 6 个新项目而不是 12 个项目,因为之前已经有 6 个项目。

这就是我的做法。分页是通过分页参数处理的。

import React from 'react';
import Router, { useRouter } from 'next/router';
import { useLazyQuery } from '@apollo/react-hooks';
import get from 'lodash/get';

const PAGE_LIMIT = 6;

const App = () => {
  const router = useRouter();
  const params = new URLSearchParams(router.query);
  const [trek, setTrek] = React.useState(params.get('trekId') || null);
  const [startDate, setStartDate] = React.useState(
    params.get('startDate') || null,
  );
  const [endDate, setEndDate] = React.useState(params.get('endDate') || null);
  const [trekDestinations, setTrekDestinations] = React.useState([]);
  const [offset, setOffset] = React.useState(0);
  const [limit, setLimit] = React.useState(PAGE_LIMIT);
  const [loadTrekDestination, { data, loading, fetchMore }] = useLazyQuery(
    FETCH_TREK_DESTINATION,
  );

  function showTrekDestination() {
    loadTrekDestination({
      fetchPolicy: 'network-only',
      notifyOnNetworkStatusChange: true,
      variables: {
        queryInput: {
          queryParams: {
            ...(region && {
              trekRegionId: [region],
            }),
            ...(trek && {
              _id: trek,
            }),
          },
          paginationParams: {
            limit: limit,
            offset: 0,
          },
        },
      },
    });
    const trekDestinations = get(data, 'getTrekkingDestinationList.data', []);
    // console.log('did mount', trekDestinations); []
    // if (trekDestinations?.dataList) {
    //   setTrekDestinations(trekDestinations);
    // }
  }

  React.useEffect(() => {
    showTrekDestination();
  }, []);

  const trekDestinations = get(data, 'getTrekkingDestinationList.data', []);

  const handleShowMoreItems = () => {
    if (trekDestinations.count > limit && trekDestinations.count !== limit) {
      setLimit(PAGE_LIMIT + limit);
    }
  };
  // searching and filtering with many parameters
  return (
    <>
      <List
        trekDestinations={trekDestinations && trekDestinations.dataList}
        handleSearch={_handleSearch}
        handleShowMoreItems={handleShowMoreItems}
        loading={loading}
      />
    </>
  );
};

export default App;

我试图将数据存储在本地状态,但在首字母渲染中我只得到空的 []。由于这将有大量数据并且搜索和过滤也在那里,所以我不知道如何有效地延迟加载这些项目。请问有人可以帮我吗?

我正在使用的堆栈是:reactjs nextjs graphql with react apollo

更新

我发现有一种方法可以使用阿波罗fetchMore功能,所以我试了一下

const onLoadMore = () => {
    fetchMore({
      variables: {
        queryInput: {
          queryParams: {
            ...(region && {
              trekRegionId: [region],
            }),
            ...(trek && {
              _id: trek,
            }),
          },
          paginationParams: {
            limit: limit,
            offset: trekDestinations.dataList.length,
          },
        },
      },
      updateQuery: (prev, { fetchMoreResult }) => {
        if (!fetchMoreResult) return prev;
        console.log('prev', prev);
        return {
          ...prev.getTrekkingDestinationList,
          data: {
            ...prev.getTrekkingDestinationList.data,
            dataList: [
              ...prev.getTrekkingDestinationList.dataList,
              ...fetchMoreResult.getTrekkingDestinationList.dataList,
            ],
          },
        };
      },
    });
  };

  const handleShowMoreItems = () => {
    onLoadMore();
  };

但出现错误Invalid attempt to spread non-iterable instance.

存在不可迭代的实例问题,因为 dataList 在数据对象内部。我这样解决了

const newResult = {
          ...fetchMoreResult,
          getTrekkingDestinationList: {
            ...fetchMoreResult.getTrekkingDestinationList,
            data: {
              ...fetchMoreResult.getTrekkingDestinationList.data,
              dataList: [
                ...prev.getTrekkingDestinationList.data.dataList,
                ...fetchMoreResult.getTrekkingDestinationList.data.dataList,
              ],
            },
          },
        };

标签: javascriptreactjsgraphqlnext.jsapollo

解决方案


推荐阅读