Using Queries
In a React Component
To use one of
your Blitz queries, call theuseQuery
hook with:- Your query function
- The input arguments for your query function
- Optionally, a configuration object.
It returns this tuple array,
[queryFunctionResults, queryExtras]
, where queryFunctionResults
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 "blitz"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.
Defaults to Keep in Mind
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.:- Query results that are currently rendered on the screen will become "stale" immediately after they are resolved and will be refetched automatically in the background when they are rendered or used again. To change this, you can alter the default
staleTime
for queries to something other than0
milliseconds. - Query results that become unused (all instances of the query are unmounted) will still be cached in case they are used again for a default of 5 minutes before they are garbage collected. To change this, you can alter the default
cacheTime
for queries to something other than1000 * 60 * 5
milliseconds. - Stale queries will automatically be refetched in the background when the browser window is refocused by the user. You can disable this using the
refetchOnWindowFocus
option in queries or the global config. - Queries that fail will silently and automatically be retried 3 times, with exponential backoff delay before capturing and displaying an error to the UI. To change this, you can alter the default
retry
andretryDelay
options for queries to something other than3
and the default exponential backoff function. - Query results by default are deep compared to detect if data has actually changed and if not, the data reference remains unchanged to better help with value stabilization with regards to useMemo and useCallback. The default deep compare function use here (
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.
Options
See
theuseQuery
documentation for a full list of possible options.Dependent Queries
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}))
Pagination
Use the
usePaginatedQuery
hookInfinite Loading
Use the
useInfiniteQuery
hookPrefetching
- All queries are automatically cached, so manually calling a query function will cache its data
Both of the following will cache the
getProject
query.const project = await getProject({where: {id: props.id}})
<a onMouseEnter={() => getProject({where: {id: projectId}})}>View Project</a>
On the Server
getStaticProps
In
getStaticProps
, a query function can be called directly without useQuery
import getProject from "app/projects/queries/getProject"export const getStaticProps = async (context) => {const project = await getProject({where: {id: context.params?.projectId}})return {props: {project}}}function ProjectPage({project}) {return <div>{project.name}</div>}export default ProjectPage
getServerSideProps
In
getServerSideProps
, pass a query function to ssrQuery
which will ensure appropriate middleware is run before/after your query function.import {ssrQuery} from 'blitz'import getProject from 'app/projects/queries/getProject'export const getServerSideProps = async ({params, req, res}) => {const project = await ssrQuery(getProject, {where: {id: params.projectId}}, {req, res}))return {props: {project}}}function ProjectPage ({project}) {return <div>{project.name}</div>}export default ProjectPage