useCartDetail.ts 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. "use client";
  2. import { useMutation } from "@apollo/client/react";
  3. import { useAppDispatch, useAppSelector } from "@/store/hooks";
  4. import { addItem } from "@/store/slices/cart-slice";
  5. import { useCallback, useEffect, useState, useRef } from "react";
  6. import { GET_CART_ITEM } from "@/graphql";
  7. import { getCartToken } from "@/utils/getCartToken";
  8. import { GetCartItemData } from "@/types/cart/type";
  9. export function useCartDetail() {
  10. const dispatch = useAppDispatch();
  11. const cart = useAppSelector((state) => state.cartDetail.cart);
  12. const [isInFlight, setIsInFlight] = useState(false);
  13. const isInFlightRef = useRef(false);
  14. const [getCartDetailMutation, { data, loading: isLoading, error }] =
  15. useMutation<GetCartItemData>(GET_CART_ITEM, {
  16. onCompleted: (response) => {
  17. const cartData = response?.createReadCart?.readCart;
  18. if (cartData) {
  19. dispatch(addItem(cartData));
  20. }
  21. },
  22. onError: (error) => {
  23. console.error("Cart detail error:", error);
  24. },
  25. });
  26. const getCartDetail = useCallback(async () => {
  27. const token = getCartToken();
  28. if (!token) {
  29. return;
  30. }
  31. if (isInFlightRef.current) return;
  32. isInFlightRef.current = true;
  33. setIsInFlight(true);
  34. try {
  35. await getCartDetailMutation();
  36. } catch (e) {
  37. throw e;
  38. } finally {
  39. isInFlightRef.current = false;
  40. setIsInFlight(false);
  41. }
  42. }, [getCartDetailMutation]);
  43. // useCartDetail在组件中被调用时就会触发useEffect
  44. useEffect(() => {
  45. if (!cart && !isInFlightRef.current) {
  46. getCartDetail();
  47. }
  48. }, [cart, getCartDetail]);
  49. return {
  50. cartData: cart || data?.createReadCart?.readCart,
  51. getCartDetail,
  52. isLoading: isLoading || (isInFlight && !cart),
  53. error,
  54. };
  55. }