javascript - React Query - useInfiniteQuery,如何在获取下一页时避免组件刷新
问题描述
已经使用 Edamam API 为我的食谱应用程序实现了无限滚动功能,但我有这个问题:
当我到达页面底部并开始获取下一页时,组件会进行完全刷新,它确实会显示每个页面的所有项目。
我想要的是,当我到达底部时,它开始获取(在底部显示我的微调器和其他东西)并在底部渲染下一页而不刷新整个页面。
这是我的代码:
const RecipesGrid = ({ query }) => {
const getRecipes = async (pageParam) => {
try {
const path = pageParam
? pageParam
: `https://api.edamam.com/api/recipes/v2?q=${query}&app_id=${process.env.REACT_APP_APP_ID}&app_key=${process.env.REACT_APP_API_KEY}&type=public`;
const response = await axios.get(path);
return response.data;
} catch (error) {
console.log(error);
}
};
useEffect(() => {
const onScroll = (event) => {
const { scrollHeight, scrollTop, clientHeight } =
event.target.scrollingElement;
if (scrollHeight - scrollTop <= clientHeight * 1.2) {
fetchNextPage();
}
};
document.addEventListener("scroll", onScroll);
return () => document.removeEventListener("scroll", onScroll);
// eslint-disable-next-line
}, []);
const {
data,
isFetching,
isFetchingNextPage,
status,
hasNextPage,
fetchNextPage,
} = useInfiniteQuery(
["recipes", query],
({ pageParam = "" }) => getRecipes(pageParam),
{
getNextPageParam: (lastPage) =>
lastPage._links.next ? lastPage._links.next.href : undefined,
}
);
if (isFetching || status === "loading") {
return <Spinner />;
}
if (status === "error") {
return <div>Whoops! something went wrong...Please, try again</div>;
}
return (
<div className={styles.Recipes}>
{data?.pages.map((item, index) => (
<React.Fragment key={index}>
{item.hits.map((recipe) => (
<Recipe recipe={recipe} key={recipe.recipe.uri} />
))}
{item.hits.length === 0 ? (
<Empty message="No results found!" />
) : null}
{!hasNextPage && item.hits.length !== 0 && (
<Empty message="No more recipes!" />
)}
</React.Fragment>
))}
{isFetchingNextPage && <Spinner />}
</div>
);
};
export default RecipesGrid;
解决方案
我认为您正在卸载整个列表,因为您只在此处呈现加载微调器:
if (isFetching || status === "loading") {
return <Spinner />;
}
isFething
每当请求进行中时始终为真。当您获取下一页时也是如此,因此您进入此早期返回并删除您的列表。从 if 语句中删除isFetching
应该可以解决它,因为无论如何您都会通过以下方式显示后台加载指示器:
{isFetchingNextPage && <Spinner />}
此外,您的错误处理将不起作用,因为您通过捕获它们进行日志记录而不是重新抛出它们将错误转换为已解决的承诺:
} catch (error) {
console.log(error);
}
请使用onError
回调来处理类似的事情。
推荐阅读
- c++ - 无法让 John Gruber 的 Web URL 正则表达式与 c++ std::regex 一起使用
- java - 安卓随机黑屏
- smartcard - 如何检查智能卡是否有效?
- python-3.x - Python 3 - 你如何重新创建你的 Pipfile?
- c# - 如何区分 Docker 中已挂载的卷和映像本机目录
- javascript - 访问 JavaScript 数组返回“未定义”
- php - 需要帮助设置谷歌日历 API
- php - Composer 在安装 FOSUserBundle 时生成内存不足错误
- node.js - 出现凉亭问题时无法安装 Foundation 6 cli
- html - 指向