Home > Software design >  Making a custom react hook to perform queries and mutations
Making a custom react hook to perform queries and mutations

Time:11-19

This is how I use the ApolloClient to perform my CRUD operations, How would I make this process reusable? I have many pages which use the same logic and writing these functions for each page is very time consuming and similar. when ever I try to use useMutation outside my functionalcomponent I get errors, may be I need to use a custom hook, how can I implement it

import { useQuery, useMutation, useLazyQuery } from '@apollo/client'

fetch query

  const {
    data: dataQuery,
    loading: loadingQuery,
    error: errorQuery,
  } = useQuery(SEARCH_ALL_ITEMS, {
    variables: { profileId },
  })

add mutation

  const [addRow, { data: dataAdd, loading: loadingAdd, error: errorAdd }] = useMutation(
    CREATE_ITEMS,
    {
      refetchQueries: [{ query: SEARCH_ALL_ITEMS, variables: { profileId } }],
      onCompleted: () => {
        notification.success({
          message: 'Success',
          description: 'Information is added',
        })
      },
    },
  )



 useEffect(() => {
      if (loadingQuery || loadingAdd || loadingDelete || loadingUpdate || loadingLazyQuery) {
        setLoading(true)
      } else {
        setLoading(false)
      },[loadingQuery, loadingAdd, loadingDelete, loadingUpdate]}

CodePudding user response:

I would go with something like this

import { useQuery, useMutation, useLazyQuery } from '@apollo/client'

export const useQueryMutation = ({query, variables: queryVariables}, 
  {mutations: { add, update, delete }}) => {
  const {
    data: dataQuery,
    loading: loadingQuery,
    error: errorQuery,
  } = useQuery(query, {
    variables: queryVariables,
  })

  const [addRow, { data: dataAdd, loading: loadingAdd, error: errorAdd }] = useMutation(
    add,
    {
      variables: mutationVariables,
      refetchQueries: [{ query, variables: queryVariables }],
      onCompleted: () => {
        notification.success({
          message: 'Success',
          description: 'Information is added',
        })
      },
    },
  );

  const [updateRow, { data: dataUpdate, loading: loadingUpdate, error: errorUpdate }] = useMutation(
    update,
    {
      refetchQueries: [{ query, variables: queryVariables }],
      onCompleted: () => {
        notification.success({
          message: 'Success',
          description: 'Information is updated ',
        })
      },
    },
  );

const [deleteRow, { data: dataDelete, loading: loadingDelete, error: errorDelete }] = useMutation(
    delete,
    {
      refetchQueries: [{ query, variables: queryVariables }],
      onCompleted: () => {
        notification.success({
          message: 'Success',
          description: 'Information is deleted ',
        })
      },
    },
  );

  return {
    query: {
      data: dataQuery,
      loading: loadingQuery,
      error: errorQuery
    },
    mutation: {
      add: {
        mutate: addRow,
        data: dataAdd,
        loading: loadingAdd,
        error: errorAdd
      }, 
      update: {
        mutate: updateRow,
        data: dataUpdate,
        loading: loadingUpdate,
        error: errorUpdate
      }, 
      delete: {
        mutate: deleteRow,
        data: dataDelete,
        loading: loadingDelete,
        error: errorDelete
      }, 
    },
   loading: loadingQuery || loadingAdd || loadingDelete || loadingUpdate || loadingLazyQuery
  }
}

and use it like

const {query: {data}, mutation: {add, update, delete}, loading} = useQueryMutation({query: SEARCH_ALL_ITEMS, variables: { profileId }, { mutation:{add: CREATE_ITEMS, update: UPDATE_ITEMS, delete: DELETE_ITEMS} });

CodePudding user response:

One solid option is GraphQL Code generator for apollo: https://www.graphql-code-generator.com/docs/plugins/typescript-react-apollo

This plugin will let you create a new file in your repo, ex: searchAllItems.graphql

and paste the graphql query / mutation inside of there (the content inside of the gql`` template function.

When you run the generator, it will create the hooks for you.

If your query is named "query SearchAllItems { ... }"

then you will have a hook called "useSearchAllItemsQuery" already setup for you.

  • Related