TanStackT
TanStack3y ago
6 replies
rubber-blue

Custom hook to handle multiple queries/mutation combined by domain e.g. useCart

So I am refactoring a code in a project and I decided to dive with React Query. One Approach I tried to use is to combine all of the queries into a single hook useCart. I thought that this would be a good idea as it will basically help me have a shared isLoading state amongst other things for the cart itself and all mutations related to it.
I still dont know if its a good idea to approach it like this, but the problem that I have encountered is that isLoading isnt really working.

export const useCartRq = () => {
  const { locale } = useLocale()

  const { data: cartData, isLoading: isCartLoading } = getCartQuery({ locale })

  const {
    mutate: addItemInCart,
    mutateAsync: addItemInCartAsync,
    isLoading: isCartAddingItemLoading,
  } = addItemInCartMutation()

  const {
    mutate: updateItemInCart,
    mutateAsync: updateItemInCartAsync,
    isLoading: isCartUpdatingItemLoading,
  } = updateItemInCartMutation()

  const {
    mutate: deleteCart,
    mutateAsync: deleteCartAsync,
    isLoading: isCartDeleteLoading,
  } = deleteCartMutation()

  const {
    mutate: convertCartCurrency,
    mutateAsync: convertCartCurrencyAsync,
    isLoading: isCartConvertingLoading,
  } = convertCartCurrencyMutation()

  const isLoading =
    isCartLoading ||
    isCartAddingItemLoading ||
    isCartUpdatingItemLoading ||
    isCartDeleteLoading ||
    isCartConvertingLoading

  return {
    cart: cartData,
    isLoading,
    addItemInCart,
    addItemInCartAsync,
    updateItemInCart,
    updateItemInCartAsync,
    deleteCart,
    deleteCartAsync,
    convertCartCurrency,
    convertCartCurrencyAsync,
  }
}


And then I would use this as:
// Called in one component
const { updateItemInCart, isLoading } = useCartRq() 

...updateItemInCart(...)...
console.log(isLoading); // works as expected

// Called in another component
const { isLoading } = useCartRq();
console.log(isLoading); // doesn't work


However if I log isCartUpdatingItemLoading within the useCartRq hook I can see that it changes to true for a brief moment, and its status is also changing as follows idle -> loading -> idle -> success

If I use the updateItemInCartMutation as a standalone hook, then obviously isLoading works as expected.

What am I missing/misunderstanding about RQ that will allow me to create a more "generalized" hook to handle "domain logic"?

P.S. What I found out is that isLoading does work if I log it in the component that is actually using updateItemInCart, however I am trying to use the isLoading in multiple other components
image.png
Was this page helpful?