👀 Check out the changes in Suspensive v2. read more →
Documentation
@suspensive/react-query
queryOptions

queryOptions

Tkdodo, The maintainer of TanStack Query explains well why this interface is needed in video explaining queryOptions in TanStack Query v5 (opens in a new tab). You can also use queryOptions in TanStack Query v4.

  1. QueryKey management becomes easier by processing queryKey and queryFn together.
  2. You can remove unnecessary custom query hooks. This is because they can all be used directly in useQuery, useQueries of TanStack Query v4, and useSuspenseQuery, useSuspenseQueries, and SuspenseQuery of Suspensive React Query.
  3. TanStack Query v5 already supports queryOptions. This Suspensive React Query's queryOptions will make migration from TanStack Query v4 to TanStack Query v5 easier.
import { queryOptions, useSuspenseQuery, useSuspenseQueries, SuspenseQuery } from '@suspensive/react-query'
import { useQuery, useQueries, useQueryClient } from '@tanstack/react-query'
 
const postQueryOptions = (postId) =>
   queryOptions({
     queryKey: ['posts', postId] as const,
     queryFn: ({
       queryKey: [, postId], // You can use queryKey.
     }) => fetch(`https://example.com/posts/${postId}`),
   })
 
// No need to create custom query hooks.
// You can use queryOptions directly in useQuery, useQueries, useSuspenseQuery, useSuspenseQueries, SuspenseQuery.
const post1Query = useQuery(postQueryOptions(1))
const { data: post1 } = useSuspenseQuery({
   ...postQueryOptions(1);
   refetchInterval: 2000, // Extensibility is clearly expressed in usage.
})
const [post1Query, post2Query] = useQueries({
   queries: [postQueryOptions(1), { ...postQueryOptions(2), refetchInterval: 2000 }],
})
const [{ data: post1 }, { data: post2 }] = useSuspenseQueries({
   queries: [postQueryOptions(1), { ...postQueryOptions(2), refetchInterval: 2000 }],
})
const Example = () => <SuspenseQuery {...postQueryOptions(1)}>{({ data: post1 }) => <>{post1.text}</>}</SuspenseQuery>
 
// You can easily use queryKey and queryFn in queryClient's methods.
const queryClient = useQueryClient()
queryClient.refetchQueries(postQueryOptions(1))
queryClient.prefetchQuery(postQueryOptions(1))
queryClient.invalidateQueries(postQueryOptions(1))
queryClient.fetchQuery(postQueryOptions(1))
queryClient.resetQueries(postQueryOptions(1))
queryClient.cancelQueries(postQueryOptions(1))
 
import { Suspense } from '@suspensive/react'
import { queryOptions, SuspenseQuery } from '@suspensive/react-query'
import { useQueryClient } from '@tanstack/react-query'
import { getPost } from './api'

const postQueryOptions = (postId: number) =>
  queryOptions({
    queryKey: ['posts', postId],
    queryFn: () => getPost(postId),
  })

export const Example = () => {
  const queryClient = useQueryClient()

  return (
    <div>
      <button onClick={() => queryClient.resetQueries(postQueryOptions(1))}>Reset Query</button>
      <Suspense fallback={<div>Loading...</div>}>
        <SuspenseQuery {...postQueryOptions(1)}>
          {({ data }) => {
            return (
              <div>
                <h1>{data.title}</h1>
                <p>{data.body}</p>
              </div>
            )
          }}
        </SuspenseQuery>
      </Suspense>
    </div>
  )
}