V5: Only previous pages infinite query (chat like infinite scroll)
Hello everyone,
In V4 i implemented an infinite list of messages, the previous pages were fetched when scrolling on top, like a chat app, it worked perfectly.
I was using this code: (i'm using trpc but i think my issue is more tanstack query related so i post here)
But now in v5, getNextPageParams is required. I tried to replace getPreviousPageParam with getNextPageParam and tweak it so i get the same behavior, but i didnt manage to. Everytime i get wrong post order since getNextPageParam is adding new page at the end and i need to add new page at the beginning so i can fetch more recent messages when scrolling top.
The only way i managed to get correct order is with this code by using only getPreviousPageParam and bypassing getNextPageParam by always returning undefined :
But when i scroll to get all previous pages and the windows is refocused the content is replaced with only the last previous fetched page.
Is it possible in v5 to implements a chat like infinite scroll ? Or i am just bad and maybe someone can share me example ?
Thanks you in advance for yout help
15 Replies
ambitious-aqua•2y ago
We made getNextPageParam mandatory because refetches can't work without it. When a refetch happens, we always start at the first page and then fetch forward from there. Wondering how refetching could've worked in v4 without getNextPageParam...
I would just implement it as a bidirectional list and just don't allow anything in the UI to fetchNextPage
other-emeraldOP•2y ago
Hmm maybe refetch didnt worked and i did not see it. I was going to do what you suggest but i wasnt sure it was the correct solution. Thanks for your response its more clear now.
i think i'm missing something, in bideractional infinite query, how would the endpoint know in which direction it should fetch since hes receiving only a cursor ?
ambitious-aqua•2y ago
You'd need to pass that information
other-emeraldOP•2y ago
I still dont understand something, when refetch happens, my endpoint is called with direction forward (which is ok) but the cursor seems to be the one returned from getPreviousPageParam instead of getNextPageParam 😕
ambitious-aqua•2y ago
can you show a reproduction ?
other-emeraldOP•2y ago
Yep, here is the repro: https://stackblitz.com/edit/tanstack-query-bs7ooo?file=src%2Fpages%2Findex.js To replicate the behavior you can load older message until there is no more and then invalidate the query in devtools.
My thinking/understanding is that on refetch the function should be called with getPreviousParams result and direction backward or getNextPageParam result with direction forward but here it is called with getPreviousParam result and direction forward.
brian-bourdon
StackBlitz
Query Load More Infinite Scroll Example (forked) - StackBlitz
Run official live example code for Query Load More Infinite Scroll, created by Tanstack on StackBlitz
ambitious-aqua•2y ago
when a refetch happens, the direction is always "forward", because we start at the first page in the cache and fetch forward from there.
and for the first page, we use the
pageParam
that we have cached, no matter where it came from
should be called with getPreviousParams result and direction backward or getNextPageParam result with direction forwardit doesn't get called with any result of either of these functions, because for the first page, they are not invoked but yeah I can see how this is not actually working because the cursor said "21" because it fetched all items before 21, but now you get all items after 21
ambitious-aqua•2y ago
it's working fine in our example though: https://stackblitz.com/github/tanstack/query/tree/main/examples/react/load-more-infinite-scroll?embed=1&theme=dark&preset=node
StackBlitz
Query Load More Infinite Scroll Example - StackBlitz
Run official live example code for Query Load More Infinite Scroll, created by Tanstack on StackBlitz
other-emeraldOP•2y ago
hmm i think i begin to understand the problem, in the tanstack example the first fetched page return a previousId of -5 which is the first item's id of the previous page. It works because the example is simplified and its implemented such that the first item's id of the previous page is predictable.
But in real use case, its not predictable, first page could be:
and the previous page:
how would you know that you should return 4 as previous Id ?
The only solution i can see is literally fetching the whole previous page just to return the id of the first item as previousId.
ambitious-aqua•2y ago
yeah I'm not sure. I think one way to fix it is for us to store the original
direction
next to pages
and pageParams
, then pass that as direction
to the first refetch. But it's quite a lot on our end. Do you see another way?other-emeraldOP•2y ago
so in this case will the first refetch have the
direction
"backward" and the others "forward" or will they all have the direction
"backward" ?ambitious-aqua•2y ago
Only the first one would have backward
other-emeraldOP•2y ago
Ok, I see. I think this should work. And to answer your previous question, after some thought, I don't really see other solution without changing a lot about how infinite query refetches works.
ambitious-aqua•2y ago
please file an issue but I'm not really sure yet if a fix is possible in a backwards compatible way
other-emeraldOP•2y ago
finally found some time to file an issue, here it is: https://github.com/TanStack/query/issues/7203
GitHub
Refetching bidirectional infinite query skipping first page · Issue...
Describe the bug I'm filling this issue after some discussions on the tanstack discord about this problem. I will try my best to explain it but the easiest way to understand it is with an examp...