Suppress `Duplicated primaryKey` console warning
Closed this issue ยท 12 comments
v2.0.4 introduced automatic Duplicated primaryKey
warning.
I call createQuery
and createSuspenseQuery
in the same file with the same options to create 2 versions of the same hook.
It allows me to have both useQuery
and useSuspenseQuery
versions too choose from, depending on the usage context.
Since they use the same queryFn
, call the same endpoint with the same params, and useSuspenseQuery
is kinda just a syntactic sugar for useQuery({ suspense: true })
, I don't think they need to have different primaryKey
.
After updating too v2.0.4 I started too see a lot off Duplicated primaryKey
warnings.
I assume they are false-positive for my setup?
Is it possible to suppress this console warning? Perhaps, by passing some new prop to options.
Also, I see Duplicated primaryKey
warning a lot during a Next.js fast recompile when working localy. But it's probably unrelated.
I don't think it's a good pattern to create two queries with the same primary key, which means this won't be a singleton.
const useUser = createSuspenseQuery()
// For rare cases you can use getOptions to subscribe or do something other
useQuery({
...useUser.getOptions(),
enabled: false
})
tRPC
uses the same pattern. There's nothing wrong with it.
When creating query procedures, it provides you both with useQuery
and useSuspenseQuery
.
tRPC
can organize this in a variable. But ReactQueryKit
is not.
I am still not suggest to implement like that. But I can do a workaround to you.
After a lot of think, I wanna remove createSuspenseQuery
and createSuspenseInfiniteQuery
and use option suspense
instead. And I know it is a big break change, but I think it will be worth.
It will also provide the best ts experience if you pass the option suspense: true
. Now you can use yarn add react-query-kit@beta
to experience it.
You can see the change of type of data
from the belown example.
type Response = { title: string; content: string }
const usePost = createQuery<Response>({
primaryKey: '/posts',
queryFn: ({ queryKey: [primaryKey] }) => {
return fetch(`${primaryKey}/1`).then(res => res.json())
}
})
function App() {
const { data } = usePost({
initialData: { title: 'string', content: 'string' },
})
console.log(data) // Response
const { data: data1 } = usePost({
variables: { id: 1 },
})
console.log(data) // Response | undefined
const { data: data2 } = usePost({ suspense: true })
console.log(data) // Response
}
IMHO, that's too radical solution for a simple console warning... ๐
useSuspenseQuery
is an official hook included in Tanstack Query v5:
Why introduce a mismatch in APIs? ๐ค
Also, if you managed to fix Typescript type definition for suspense: true
, it might be worth opening a PR with those changes to @tanstack/query repo
It is not just a console warning., because it is too annoying to change plain query to suspense query and vice versa. Think of that if u pass some middleware in a custom query hook.
first scene
const useUser = createQuery({
// ...
use: [m1, m2, m3]
})
And it will miss these middleware if you via getOptions
get the options to useSuspenseQuery
useSuspenseQuery(useUser.getOptions())
second scene
If you want to get two types of queries, then you must call createQuery
and createSuspenseQuery
to achieve it. I think this is very inelegant.
const useUser = createQuery({
primaryKey: "user'
})
const useSuspenseUser = createSuspenseQuery({
primaryKey: "user'
})
Finnally this is just a beta
version, I will not include this featrue in release
version unless you guys buy this idea
FYI, from a pure react-query perspective, we've moved away from the suspense:boolean
flag in the public api. If you rely on this, it might not work in the future.
The reason is that suspense
is not just a flag you can turn off or on - it's an architectural pattern. It changes how you need to structure components and how / where you have to do prefetching. Suspense also runs on the server with next13 app directory, normal queries don't. We might also integrate with a suspense-cache from react in the future (if that becomes a real thing), all of which led us to use a separate hook for suspense.
Also, the API is different. There is no placeholderData
for suspense because it can never be shown. There is no keepPreviousData
because with suspense, you want transitions.
I call createQuery and createSuspenseQuery in the same file with the same options to create 2 versions of the same hook.
I don't know much about react-query-kit, but in react-query v5, you'd use the queryOptions
api for that:
const todoOptions = queryOptions({
queryKey: ['todos'],
queryFn: fetchTodos,
staleTime: 5000,
})
usage:
useQuery(todoOptions)
useSuspenseQuery(todoOptions)
queryClient.prefetchQuery(todoOptions)
const data = queryClient.getQueryData(todoOptions.queryKey)
// โฌ๏ธ data returned here is typed to whatever fetchTodos returns!
@TkDodo Thank you for explaining this. This idea will be abandoned.
In addition. I found a bug with "queryOptions". Hopes to fix it.
type BizError = Error
const todoOptions = queryOptions<string, BizError>({
queryKey: [`todo`],
queryFn: () => 'dsa',
})
// this is will not work if u manualy set `BizError` to todoOptions
useQueries({
queries: [todoOptions],
})
Seems there need to infer TError
to fixed this bug. https://github.com/TanStack/query/blob/3e1f3ce412af007066efbc41678d2e72c9e5d325/packages/react-query/src/useQueries.ts#L68
Seems there need to infer TError to fixed this bug.
the useQueries
types are a mystery to me ๐
. If you can, please provide a fix for this. Apart from that, my suggestion is to never provide generics via <>
but to infer them.
Errors cannot be inferred, but that's for a reason as there is no guarantee that you'll always get a BizError
. You'll get a "normal" Error if something goes wrong in the select
function for example. There's no way to enforce that statically, and the recommended way is to keep things typed to Error
and use type-narrowing at runtime.
However, if you don't want that, you can provide a global type for all Errors via module augmentation in v5:
https://tanstack.com/query/v5/docs/react/typescript#registering-a-global-error
@snelsi Already remove Duplicated primaryKey console warning in v2.0.6