Getting Started with React Query
React Query is a data-fetching library for React and for React Native. It makes fetching, caching, synchronising, and updating server state in your react application easier.
Install the package
yarn add @tanstack/react-query
yarn add -D @tanstack/react-query-devtools
yarn add @tanstack/react-query-persist-client
# if it's React
yarn add @tanstack/query-sync-storage-persister
# if it's React Native
yarn add @tanstack/query-async-storage-persister
Query
A query is a declarative dependency on an asynchronous source of data that is tied to a unique key.
const { isLoading, error, data: jobsResponse } = useQuery('jobs', async () => {
return await apis.getJobs(companyId)
}, {
enabled: !!companyId,
})
The unique key, jobs
, is used internally for refetching, caching, and sharing your queries throughout the application.
Sometimes, your userQuery
can depend on the value of a variable which is a result of another async operation. In that case, you use enabled
option. The enabled
option is used to toggle the query on and off. When enabled
is false, the query will not run even when companyId
changes.
refetch
On my mobile app, I implemented a gesture that you pull down the list and it refetches the data again. useQuery
support refetch
const {
isLoading : isJobLoading,
data: jobs,
refetch: jobsRefetch
} = useQuery('jobs', async () => {
const jobsResponse = await apis.getJobs(user?.companyId || '')
return jobsResponse.data
}, {
enabled: !!user?.companyId,
})
...
<JobItems
items={jobs || []}
refetch={jobsRefetch}
/>
type JobItemsProps = {
items: Job[]
refetch: () => Promise<QueryObserverResult<Job[] | undefined, unknown>>
}
const JobItems = (props: JobItemsProps) => {
const { items, refetch } = props
...
<KeyboardAwareScrollView
contentContainerStyle=
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={() => void refetch().then()}
/>
}
>
Mutation
Use useMutation
to save or update data.
Do refetch
after the mutation succeeds
const completeMutation = useMutation(async (job: Job) => {
const response = await apis.updateJob({
...job,
jobStatus: JobStatus.COMPLETED,
})
if (response.status !== 200) {
toast.show({
title: 'Job failed to update into the app server',
status: 'error',
description: response.message,
})
throw new Error('Job failed to update into the app server')
}
toast.show({
title: 'Successfuly updated',
status: 'success',
description: `Job status has been successfully updated to '${response.data.jobStatus}.'`,
})
await getJobQuery.refetch()
return response
})
const handleComplete = (job?: Job) => {
setShowCompletedModal(false)
if (!job) {
return
}
...
completeMutation.mutate(job)
}
Testing
React Query works by means of hooks. Writing unit tests for the custom hooks can be done by means of the react-hooks-testing-library.
Offline
I use React Query in my React Native mobile app to support offline feature. To test offline feature, you can install Network Link Conditioner from Apple.
Comments