Debaucus
Debaucus13mo ago

TRPC -useInfiniteQuery() refreshes all data when an input is varied, how to use?

So I have a TRPC infiniteQuery:
const { data, fetchNextPage, hasNextPage } =
trpc.server.getAll.useInfiniteQuery(
{
limit: 3,
tag: page,
},
{
getNextPageParam: (lastPage) =>
lastPage[lastPage.length - 1]?.nextCursor ?? null,
}
);
const { data, fetchNextPage, hasNextPage } =
trpc.server.getAll.useInfiniteQuery(
{
limit: 3,
tag: page,
},
{
getNextPageParam: (lastPage) =>
lastPage[lastPage.length - 1]?.nextCursor ?? null,
}
);
As an example, for each 3 gathered, I increase the value of page by 1, when page = 2, the page does a query, resets the pages content and triggers a repeating loop of queries. I want to pass a varying value, be it string or number, to the query and be able to continue from the old content. Any help is welcome
5 Replies
Debaucus
Debaucus13mo ago
keepPreviousData: true, Doesn't work either. Thought that might be it.
Alex / KATT 🐱
Alex / KATT 🐱13mo ago
seems to be how it's working out-of-the box i.e. look at https://nextjs.trpc.io/ press "load more" a few times, click a list item and click back
Debaucus
Debaucus13mo ago
Does that have a changing input by default? The bit that is confusing me is that if I change the input. So for example:
.input(
z.object({
limit: z.number(),
// cursor is a reference to the last item in the previous batch
// it's used to fetch the next batch
cursor: z.string().nullish(),
skip: z.number().optional(),
})
)
.query(async ({ ctx, input }) => {
const { limit, skip, cursor } = input;

const tagsList = "free-to-play,testing,survival,444,custom-game-1";
const tagListFullSplit = tagsList?.split(",");
const tagToSelect = Math.floor(Math.random() * 5);

const allSocialServers = await ctx.prisma?.server.findMany({
where: {
AND: [
{ published: true },
{ nsfw: false },
{ serverTags: { contains: tagListFullSplit[tagToSelect] } },
{
OR: [
{ serverTypes: { contains: "Telegram" } },
{ serverTypes: { contains: "Discord" } },
],
},
],
},
orderBy: [{ votesDaily: "desc" }, { id: "desc" }],
take: limit + 1,
skip: skip,
cursor: cursor ? { id: cursor } : undefined,
});
.input(
z.object({
limit: z.number(),
// cursor is a reference to the last item in the previous batch
// it's used to fetch the next batch
cursor: z.string().nullish(),
skip: z.number().optional(),
})
)
.query(async ({ ctx, input }) => {
const { limit, skip, cursor } = input;

const tagsList = "free-to-play,testing,survival,444,custom-game-1";
const tagListFullSplit = tagsList?.split(",");
const tagToSelect = Math.floor(Math.random() * 5);

const allSocialServers = await ctx.prisma?.server.findMany({
where: {
AND: [
{ published: true },
{ nsfw: false },
{ serverTags: { contains: tagListFullSplit[tagToSelect] } },
{
OR: [
{ serverTypes: { contains: "Telegram" } },
{ serverTypes: { contains: "Discord" } },
],
},
],
},
orderBy: [{ votesDaily: "desc" }, { id: "desc" }],
take: limit + 1,
skip: skip,
cursor: cursor ? { id: cursor } : undefined,
});
This works for example, however, I already have the pre-set values. If I send the serverTags: value in the query from the file (shown as tag:) I get constant resets. Ultimately, here is my question. How do you correctly infiniteQuery when changing an input value? Request 3 of tag: x, then, a new query is triggered for request 3 of tag: y, results of tag: x get overwritten or replaced? At least when I use an array with an index selector number value. I apologise if I'm coming across blunt or rude, it's not intended, I've been on this for a few days 😅 I'm just very confused why (what I imagine) a common need is giving me strange behaviour
Alex / KATT 🐱
Alex / KATT 🐱13mo ago
this seems like a react query issue more than a trpc one - is it that you want to retain the state whenever you switch type? could you ask over at the tanstack discord? i am not sure how to help with this there might be some way of instructing infinite query to always show everything that is in the cache
Debaucus
Debaucus12mo ago
That would be it yes, maybe storing the state would work? Seems to defeat the point of keepPreviousData: true 😅 After lots of ChatGPT work and a good break, I have a better understanding, but now I have more questions 😅 This behavior is happening because when you change the tag value in the query, it triggers a new query with the updated tag value. This causes the previous data to be replaced with the new data returned from the updated query. Does TRPC have an option that works like this?
const tagListFullSplit = tagsList?.split(",");
const results = useQueries(
tagListFullSplit.map((tag) => ({
queryKey: ["socialServers", tag],
queryFn: () =>
trpc.server.getAllSocialServers({
limit: 3,
tag,
}),
}))
);
const tagListFullSplit = tagsList?.split(",");
const results = useQueries(
tagListFullSplit.map((tag) => ({
queryKey: ["socialServers", tag],
queryFn: () =>
trpc.server.getAllSocialServers({
limit: 3,
tag,
}),
}))
);
This will return an array of query results, one for each tag. You can then merge the results from all queries into a single array and display them as desired.This will return an array of query results, one for each tag. You can then merge the results from all queries into a single array and display them as desired. If not, I believe my best approach is to trigger a normal query a stack an array client side with all the results. Same affect really.