⚛ React Query with GraphQL
11 Nov, 2021
👋 FYI, this note is over 6 months old. Some of the content may be out of date.
On this page
Two hooks are provided to make it easier to work with GraphQL and React Query. They use graphql-request
to make the requests to the GraphQL server.
GraphQL client used in the following examples
import { GraphQLClient } from 'graphql-request'
const endpoint = `${import.meta.env.VITE_HASURA_ENDPOINT}`
export const graphQlClient = new GraphQLClient(endpoint)
useGqlQuery
Jump to heading
A wrapper around “useQuery”
Source Jump to heading
import {
QueryKey,
useQuery,
UseQueryOptions,
UseQueryResult,
} from 'react-query'
import { auth } from '../../config'
import { graphQlClient } from '../../graphql/client'
/**
* @name useGqlQuery
* @description a helper hook that should be used when calling the GraphQL API
*/
export const useGqlQuery = <ResponseData = unknown, Variables = unknown>(
queryKey: QueryKey,
query: string,
variables?: Variables,
options?: UseQueryOptions<ResponseData, Error, ResponseData, QueryKey>
): UseQueryResult<ResponseData, Error> => {
return useQuery(
queryKey,
async () => {
try {
// always get the latest token
// this uses Firebase Authentication to get a token
const token = await auth?.currentUser?.getIdToken()
// if the token is `undefined`, no auth headers will be set
// this allows us to use the GraphQL API for public queries
const authorisationHeaders = token
? {
Authorization: `Bearer ${token}`,
}
: undefined
const response = await graphQlClient.request(
query,
variables,
authorisationHeaders
)
return response
} catch (error) {
console.log(`🚀 ~ useGqlQuery ~ error`, error)
}
},
options
)
}
Usage Jump to heading
export const GET_SHORTLIST = gql`
query ($from_id: uuid!) {
contact_connection(
where: {
from_id: { _eq: $from_id }
_and: { row_status: { _eq: "active" } }
}
) {
to_id
}
}
`
interface ShortlistItem {
to_id: string
}
interface QueryData {
contact_connection: ShortlistItem[]
}
interface QueryVariables {
from_id: string
}
const getShortlistQuery = useGqlQuery<QueryData, QueryVariables>(
'queryKey',
GET_SHORTLIST,
{
from_id: '1234557565675',
}
)
const shortlist = useMemo(() => getShortlistQuery?.data[getShortlistQuery])
useGqlMutation
Jump to heading
A wrapper around useMutation
Source Jump to heading
import { useMutation, UseMutationResult, UseMutationOptions } from 'react-query'
import { auth } from '../../config'
import { graphQlClient } from '../../graphql/client'
/**
* @name useGqlMutation
* @description a helper hook that should be used when mutating data with the GraphQL API
*/
export const useGqlMutation = <Response = unknown, Variables = unknown>(
query: string,
sideEffects?: UseMutationOptions<Response, Error, Variables, unknown>
): UseMutationResult<Response, Error, Variables, unknown> => {
return useMutation(async (variables) => {
// always get the latest token
// this uses Firebase Authentication to get a token
const token = await auth?.currentUser?.getIdToken()
return graphQlClient.request(query, variables, {
Authorization: `Bearer ${token}`,
})
}, sideEffects)
}
Usage Jump to heading
export const REMOVE_SHORTLIST = gql`
mutation ($from_id: uuid!, $to_id: uuid!) {
update_contact_connection(
where: { from_id: { _eq: $from_id }, to_id: { _eq: $to_id } }
_set: { row_status: "inactive" }
) {
affected_rows
returning {
to_id
}
}
}
`
interface ShortlistItem {
to_id: string
}
interface MutationResponse {
update_contact_connection: {
affected_rows: number
returning: ShortlistItem[]
}
}
interface MutationVariables {
from_id: string
to_id: string
}
const removeShortlist = useGqlMutation<MutationResponse, MutationVariables>(
REMOVE_SHORTLIST,
{
onSuccess: (data, variables) => {
queryClient.invalidateQueries('myShortlist')
console.log(`🚀 ~ mutation variables`, variables)
console.log(`🚀 ~ mutation data`, data)
},
}
)
← Back home