GraphQL Hasura with React Query-useMutation & useQuery Hooks — Part 2
This article focuses on `useQuery` & `useMutation` hooks of React Query
1. useQuery — use this hook when we want to fetch data from remote server or any other source
Call useQuery
hook with at least :
- Unique Key name for query
- Function returning Promise which either resolves data or throws error
Let’s talk about code implementation now .We have folder hasura-graphql
with file queries/user.js
which contains graphql query for Hasura hosted instance which we created in previous article and another folder react-query
which contains queries/user.js
. In this we have useQuery
hook which wraps graphql
query.
hasura-graphql/queries/user.js
contains below code -
import graphQLRequest from '../service'const userData = async ({ email }) => {
try {
const query = `
query User($email:String!) {
users_by_pk(email:$email) {
name
}
}
`const qv = { email: email }
const user = await graphQLRequest({
query,
variables: qv
})
return user
} catch (error) {
throw error
}
}export { userData }
In above code we have created a graphql query to fetch users email & name and calling that query via graphQLRequest wrapper function
react-query/queries/user.js
contains below code -
import { useQuery } from 'react-query'
import { userData } from '../../hasura-graphql/queries/user'async function userProfile(email) {
const data = await userData({ email })
return data
}function useUserData() {
return useQuery(['userData'], userProfile, {
initialData: {
name: 'test_user',
email: 'test@test.com',
},
initialStale: true,
refetchOnMount: true,
refetchOnWindowFocus: false,
})
}export { useUserData }
In above code we have used useQuery
hook with userData
as key & userProfile
as function which is calling userData()
function from hasura-graphql/queries/user.js
Now we can import & call above hook anywhere in our app , for reference we are calling it in App.js as follows
import { useUserData } from './react-query/queries/user' // query user
const { status: userDataStatus,
data: userData,
error: userDataErr
} = useUserData()useEffect(
() => {
console.log(userDataStatus, userData, userDataErr)
},
[ userData, userDataErr, userDataStatus ])
That’s all with useQuery
, in case for more complex use cases have a look at documentation.
2. useMutation — use this hook to perform server side-effects or create/update/delete data
Similar to query , we have folder named hasura-graphql
with file mutations/user.js
which contains graphql mutation for Hasura which insert
user with email, name
as parameters and another folder name react-query
which contains mutations/user.js
which has useMutation
hook which wraps above graphql
mutation.
hasura-graphql/mutations/user.js
contains below code -
import graphQLRequest from '../service'async function updateUserProfile({ email, name }) {
try {
const query = `
mutation addUser($email:String!,$name:String!,) {
insert_users(objects: {email: $email, name: $name, }}}) {
affected_rows
returning {
}
}
}`const qv = { email: email, name: name }
const data = await graphQLRequest({ query, variables: qv })
return data
} catch (error) {
throw error
}
}export { updateUserProfile }
react-query/mutations/user.js
contains below code -
import { useMutation } from 'react-query'
import { updateUserProfile } from '../../hasura-graphql/mutations/user'const useUpdateUserData = () =>
useMutation(
async (data) => {
return await updateUserProfile(data)
},
{
onMutate: (editedValue) => {
// console.log(data, error, editedValue)
}, onError: (error, editedValue) => {
console.log(error, editedValue)
}, onSettled: (data, error, editedValue) => {
// console.log(data, error, editedValue)
}, onSuccess: (data, variables) => {
// console.log(data, variables)
}
}
)export { useUpdateUserData }
In above code we have used useMutation
hook which is calling hasura graphql mutation side effects and giving below event function -
- onMutate — A mutation is about to happen
- onError — Error happend
- onSettled — Always executes irrespective of Error/Success
- onSuccess — Success in Execution
Now we can import & call above hook anywhere in our app , for reference we are calling it in App.js as follows -
import { useUpdateUserData } from './react-query/mutations/user'// mutate user
const {
mutateAsync: updateUser,
status: userUpdateStatus,
isLoading: isLoadingUserUpdate,
data: userUpdateData,
error: userUpdateErr
} = useUpdateUserData()useEffect(() =>
{ console.log()},
[ userUpdateData, userUpdateErr,
isLoadingUserUpdate, userUpdateStatus ]
)// call mutate function with input parameters
updateUser({ email, name })
A mutation can only be in one of the following states at any given moment:
status === 'idle'
- The mutation is currently idle statestatus === 'loading'
- The mutation is currently runningstatus === 'error'
- The mutation encountered an errorstatus === 'success'
- The mutation was successful and mutation data is available
Beyond those primary states, more information is available depending on the state of the mutation:
error
- If the mutation is in anerror
state, the error is available via theerror
property.data
- If the mutation is in asuccess
state, the data is available via thedata
property.
That’s all with useQuery
, in case for more complex use cases have a look at documentation