⚛React Query with GraphQL
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
A wrapper around “useQuery”
Source
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
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
A wrapper around useMutation
Source
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
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)
},
}
)