Situation: I want to make infinite scroll for my project. Currently, I’m using Javascript fetching API
but want to apply react-query
instead of.
Problem: React query is a form of Hook so can’t be nested inside of useCallback
.
Below codes are my current infinite scroller.
function RQInfiniteScrollTable({src}:{src:string}){
const [page,setPage] = useState(1);
const [pageData,setPageData]:[pageData:Array<object>,setPageData:any] = useState([]);
const loadMore = useCallback(async () => {
const new_page = page + 1;
setPage(new_page);
const buffer: Array<object> = [...pageData];
let moreData:Response|null = await fetch([src,new_page].join("/").trim());
let moreData_json:object|null = await moreData.json();
if(moreData_json === null){return;}
buffer.push(moreData_json);
setPageData(buffer);
return ()=>{moreData = null; moreData_json = null;};
},[pageData]);
const products:Array<React.ReactNode> = [];
// @ts-ignore
pageData.forEach(({title,image,price,category,description},index):void=>{
products.push(
<div key={index} className={"infinite-item-card"}>
<div className={"w-full h-64 relative"}>
<Image src={image} alt={title} layout={"fill"} objectPosition={"cover"} objectFit={"cover"}/>
</div>
<h1>{title}</h1>
<p>{price}</p>
<p>{category}</p>
<p>{description}</p>
</div>
);
});
return(
<div className={"w-full grid justify-items-center"}>
<h1 className={"text-2xl w-fit my-8"}>{"Infinite Scroller"}</h1>
<div className={"grid"}>{products}</div>
<InfiniteScroller loadMore={loadMore}/> <-- this node callbacks given `loadMore` function when intersected.
</div>
);
}
Question: how to solve this problem? I want to use react-query
for better handling, with optimized way. and does query result of useQuery
trigger re-render of the component?
2
Answers
I solve this problem! thanks for suggesting above. I created
onChange
state for dependency for Observer'suseCallback
I’d suggest defining a query that takes the page number as a parameter, and then including that parameter in the query key. Then, whenever you update the page number, react-query will take care of automatically fetching the result. Here’s a mock version I’ve sketched up:
useGetPaginatedDataQuery.tsx
RQInfiniteScrollTable.tsx