Skip to content

Commit 11c9f00

Browse files
Daidalos117Roman Rajchert
andauthored
Fix/4407 set query data use inifinite query (#4413)
* fix(4407): setQueryData with useInifiniteQuery * chore(4407): merge develop * fix(4407): typing * chore(4407): add changeset * chore(4407): remove prefetch on infninite mutate page * chore(4407): recreate changeset * fix(4407): mutating data in infinite * fix(4407): remove web from changeset --------- Co-authored-by: Roman Rajchert <roman.rajchert@vodafone.com>
1 parent ce1a603 commit 11c9f00

File tree

4 files changed

+113
-6
lines changed

4 files changed

+113
-6
lines changed

.changeset/new-toys-occur.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@blitzjs/rpc": patch
3+
---
4+
5+
fix(4407): setQueryData with useInfiniteQuery
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import {useSuspenseInfiniteQuery} from "@blitzjs/rpc"
2+
import getInfiniteUsers from "src/queries/getInfiniteUsers"
3+
import {useActionState} from "react"
4+
5+
function PageWithInfiniteQueryMutate(props) {
6+
const [usersPages, extraInfo] = useSuspenseInfiniteQuery(
7+
getInfiniteUsers,
8+
(page = {take: 3, skip: 0}) => page,
9+
{
10+
getNextPageParam: (lastPage) => lastPage.nextPage,
11+
initialPageParam: {take: 3, skip: 0},
12+
},
13+
)
14+
const {isFetchingNextPage, fetchNextPage, hasNextPage, setQueryData} = extraInfo
15+
16+
const onOnContactSave = async (previousState, formData: FormData) => {
17+
const name = formData.get("name") as string | null
18+
19+
await setQueryData(
20+
(oldData) => {
21+
if (!oldData) {
22+
return {
23+
pages: [],
24+
pageParams: [],
25+
}
26+
}
27+
28+
return {
29+
...oldData,
30+
pages: oldData.pages.map((page, index) => {
31+
if (index === 0) {
32+
return {
33+
...page,
34+
users: [
35+
{
36+
id: Math.random(),
37+
name,
38+
role: "user",
39+
email: `${name}@yopmail.com`,
40+
createdAt: new Date(),
41+
updatedAt: new Date(),
42+
hashedPassword: "alsdklaskdoaskdokdo",
43+
},
44+
...page.users,
45+
],
46+
}
47+
}
48+
return page
49+
}),
50+
}
51+
},
52+
{refetch: false},
53+
)
54+
}
55+
56+
const [, formAction] = useActionState(onOnContactSave, {name: ""})
57+
58+
return (
59+
<div>
60+
<form action={formAction}>
61+
<input type="text" name="name" placeholder="User name" />
62+
<button type="submit">Add user</button>
63+
</form>
64+
{usersPages.map((usersPage) => (
65+
<>
66+
{usersPage?.users.map((u) => (
67+
<div key={u.name}>
68+
<p>name: {u.name}</p>
69+
<p>role: {u.role}</p>
70+
<p>email: {u.email}</p>
71+
<hr />
72+
</div>
73+
))}
74+
75+
{usersPage.hasMore && (
76+
<button onClick={() => fetchNextPage()} disabled={!hasNextPage || !!isFetchingNextPage}>
77+
{isFetchingNextPage
78+
? "Loading more..."
79+
: hasNextPage
80+
? "Load More"
81+
: "Nothing more to load"}
82+
</button>
83+
)}
84+
</>
85+
))}
86+
</div>
87+
)
88+
}
89+
90+
export default PageWithInfiniteQueryMutate

packages/blitz-rpc/src/query/react-query/react-query.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {
3939
sanitizeQuery,
4040
sanitizeMutation,
4141
getInfiniteQueryKey,
42+
QueryType,
4243
} from "../utils"
4344
import {useRouter} from "next/compat/router"
4445

@@ -282,7 +283,7 @@ export function usePaginatedQuery<
282283
// -------------------------
283284
export interface RestInfiniteResult<TResult, TError>
284285
extends Omit<UseInfiniteQueryResult<TResult, TError>, "data">,
285-
QueryCacheFunctions<TResult> {
286+
QueryCacheFunctions<InfiniteData<TResult>> {
286287
pageParams: any
287288
}
288289

@@ -355,7 +356,7 @@ export function useInfiniteQuery<
355356

356357
const rest = {
357358
...queryRest,
358-
...getQueryCacheFunctions<FirstParam<T>, TResult, T>(queryFn, getQueryParams),
359+
...getQueryCacheFunctions<FirstParam<T>, InfiniteData<TResult>, T>(queryFn, getQueryParams),
359360
pageParams: infiniteQueryData?.pageParams,
360361
}
361362

@@ -367,7 +368,7 @@ export function useInfiniteQuery<
367368
// -------------------------
368369
export interface RestInfiniteResult<TResult, TError>
369370
extends Omit<UseInfiniteQueryResult<TResult, TError>, "data">,
370-
QueryCacheFunctions<TResult> {
371+
QueryCacheFunctions<InfiniteData<TResult>> {
371372
pageParams: any
372373
}
373374

@@ -449,7 +450,11 @@ export function useSuspenseInfiniteQuery<
449450

450451
const rest = {
451452
...queryRest,
452-
...getQueryCacheFunctions<FirstParam<T>, TResult, T>(queryFn, getQueryParams),
453+
...getQueryCacheFunctions<FirstParam<T>, InfiniteData<TResult>, T>(
454+
queryFn,
455+
getQueryParams,
456+
QueryType.INFINITE,
457+
),
453458
pageParams: infiniteQueryData?.pageParams,
454459
}
455460

packages/blitz-rpc/src/query/utils.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,10 @@ export interface QueryCacheFunctions<T> {
6565
export const getQueryCacheFunctions = <TInput, TResult, T extends AsyncFunc>(
6666
resolver: T | Resolver<TInput, TResult> | RpcClient<TInput, TResult>,
6767
params: TInput,
68+
queryType: QueryType = QueryType.STANDARD,
6869
): QueryCacheFunctions<TResult> => ({
6970
setQueryData: (newData, opts = {refetch: true}) => {
70-
return setQueryData(resolver, params, newData, opts)
71+
return setQueryData(resolver, params, newData, opts, queryType)
7172
},
7273
})
7374

@@ -170,16 +171,22 @@ export const invalidateQuery: InvalidateQuery = (resolver = undefined, ...params
170171
})
171172
}
172173

174+
export enum QueryType {
175+
STANDARD = "STANDARD",
176+
INFINITE = "INFINITE",
177+
}
173178
export function setQueryData<TInput, TResult, T extends AsyncFunc>(
174179
resolver: T | Resolver<TInput, TResult> | RpcClient<TInput, TResult>,
175180
params: TInput,
176181
newData: TResult | ((oldData: TResult | undefined) => TResult | undefined),
177182
opts: MutateOptions = {refetch: true},
183+
queryType: QueryType = QueryType.STANDARD,
178184
): Promise<void | ReturnType<ReturnType<typeof getQueryClient>["invalidateQueries"]>> {
179185
if (typeof resolver === "undefined") {
180186
throw new Error("setQueryData is missing the first argument - it must be a resolver function")
181187
}
182-
const queryKey = getQueryKey(resolver, params)
188+
const getQueryKeyFn = queryType === QueryType.STANDARD ? getQueryKey : getInfiniteQueryKey
189+
const queryKey = getQueryKeyFn(resolver, params)
183190

184191
return new Promise((res) => {
185192
getQueryClient().setQueryData(queryKey, newData)

0 commit comments

Comments
 (0)