To use one of your Blitz queries, call the useQuery
hook with:
It returns this tuple array,[queryResult, queryExtras]
, where
queryResult
is exactly what's returned from your query function.
useQuery
is built on
react-query
, so it
automatically provides awesome features such as automatic caching and
revalidation.
import { useQuery } from "@blitzjs/rpc"
import getProject from "app/projects/queries/getProject"
function App() {
const [project] = useQuery(getProject, { where: { id: 1 } })
}
For complete details, see the useQuery
documentation.
You may be wondering how that can work since it's importing server code into your component: At build time, the direct function import is swapped out with a network call. So the query function code is never included in your client code.
Out of the box, useQuery
and the other query hooks are configured with
aggressive but reasonable defaults. Sometimes these defaults can
catch new users off guard or make learning/debugging difficult if they are
unknown by the user.:
staleTime
for queries to
something other than 0
milliseconds.cacheTime
for queries to something other
than 1000 * 60 * 5
milliseconds.refetchOnWindowFocus
and
refetchOnReconnect
options in queries.retry
and retryDelay
options for queries.config.isDataEqual
) only supports comparing JSON-compatible
primitives. If you are dealing with any non-json compatible values in
your query responses OR are seeing performance issues with the deep
compare function, you should probably disable it
(config.isDataEqual = () => false
) or customize it to better fit your
needs.See the useQuery
documentation for a full list of
possible options.
Dependent queries are queries that depend on previous ones to finish before they can execute. To do this, use the enabled option to tell a query when it is ready to turn on:
const [user] = useQuery(getUser, { where: { id: props.query.id } })
const [projects] = useQuery(getProjects, { where: { userId: user.id } }, { enabled: user }))
Use the usePaginatedQuery
hook
Use the useInfiniteQuery
hook
All queries are automatically cached, so both of the following will cache
the getProject
query.
import { invoke } from "@blitzjs/rpc"
const project = await invoke(getProject, { where: { id: props.id } })
<a onMouseEnter={() => invoke(getProject, { where: { id: props.id } })}>
View Project
</a>
Blitz also supports prefetching multiple queries on the server and then dehydrating those queries to the internal query client. This allows Blitz to prerender markup that is immediately available on page load. Once JavaScript is available in the browser, Blitz will hydrate those queries and refetch them if they have become stale since the time they were rendered on the server.
The following example demonstrates how prefetching works in Blitz.
import { gSSP } from "app/blitz-server"
import getProject from "app/projects/queries/getProject"
export const getServerSideProps = gSSP(async ({ ctx }) => {
// IMPORTANT: the second argument to prefetchBlitzQuery must exactly match the second argument to useQuery down below
await context.prefetchBlitzQuery(getProject, {
where: { id: context.params?.projectId },
})
return { props: {} }
})
function ProjectPage(props) {
const [project] = useQuery(getProject, { where: { id: props.id } })
return <div>{project.name}</div>
}
export default ProjectPage
To ensure data is not shared between users and requests, a new query
client is created for each page request. You can prefetch your data by
invoking the prefetchBlitzQuery
method which is available on the ctx
object, passing in the resolver along with any relevant input arguments.
Once the data has been fetched, Blitz handles dehydrating the queries to
the query client.
Blitz supports the default React Query's way to cancel queries. You can read more about it here.
You can also manually cancel queries by using cancelQueries
method:
import { getQueryClient, getQueryKey, useQuery } from "@blitzjs/rpc"
const [data] = useQuery(getTodos)
return (
<button
onClick={(e) => {
e.preventDefault()
getQueryClient.cancelQueries(getQueryKey(getTodos))
}}
>
Cancel
</button>
)
In getStaticProps
or getServerSideProps
, a query & mutation function can be called directly.
getStaticProps
import getProject from "app/projects/queries/getProject"
import { gSP } from "app/blitz-server"
export const getStaticProps = gSP(async ({ params, ctx }) => {
const project = await getProject({
where: { id: context.params?.projectId },
})
return { props: { project } }
})
function ProjectPage({ project }) {
return <div>{project.name}</div>
}
export default ProjectPage
getServerSideProps
import getProject from "app/projects/queries/getProject"
import { gSSP } from "app/blitz-server"
export const getServerSideProps = gSSP(async ({ params, ctx }) => {
const project = await getProject({
where: { id: params.projectId }
}),
return { props: { project } }
})
function ProjectPage({ project }) {
return <div>{project.name}</div>
}
export default ProjectPage