javascript - 在 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,
],
},
},
};
解决方案
推荐阅读
- android - 如何在android端访问flutter Shared首选项(使用java)
- python - 遇到 Import Error DLL load 不断失败
- json - 基于另一个模式对象对 json 模式使用条件语句
- windows - 如何将命令输出设置为 env。windows cmd中的变量?
- java - springMVC 中的@RequestAttribute 没有绑定实体类的对象
- javascript - 在 Jquery 每个循环中使用 TypeScript 变量
- r - 如何在openxlsx生成的XLSX中允许按年、月、日过滤
- azure - 用 ADFS 替换 AD 的最简单方法(或将其添加到它上面)?
- jquery - CSS:“前沿”设计。如何?
- metadata - Icecast/Shoutcast 广播流:提取正在播放的信息