Ver código fonte

useCartDetail 优化;airwallex卡支付初始化优化

fogwind 2 dias atrás
pai
commit
09f2213fb0

+ 4 - 3
src/components/cart/CartModal.tsx

@@ -9,7 +9,7 @@ import { Price } from "../theme/ui/Price";
 import CloseCart from "../common/icons/cart/CloseCart";
 import { DeleteItemButton } from "../common/icons/cart/DeleteItemButton";
 import { EditItemQuantityButton } from "../common/icons/cart/EditItemQuantityButton";
-import { useCartDetail } from "@utils/hooks/useCartDetail";
+import { useAppSelector } from "@/store/hooks";
 import Image from "next/image";
 import { NOT_IMAGE } from "@utils/constants";
 import LoadingDots from "@components/common/icons/LoadingDots";
@@ -49,8 +49,9 @@ export default function CartModal({
   const finalOnOpen = isControlled ? onOpen : internalOnOpen;
   const finalOnClose = isControlled ? onClose : internalOnClose;
 
-  const { isLoading, cartData: cartDetail } = useCartDetail();
-  // const cartDetail = useAppSelector((state) => state.cartDetail);
+  // const { isLoading, cartData: cartDetail } = useCartDetail();
+  const cartState= useAppSelector((state) => state.cartDetail);
+  const {cart:cartDetail, loading: isLoading} = cartState;
   const cart = Array.isArray(cartDetail?.items?.edges)
     ? cartDetail?.items?.edges
     : [];

+ 2 - 19
src/lib/Airwallex/airwallexInit.ts

@@ -47,15 +47,6 @@ class AirwallexManager {
   private elements: AirwallexCardElements = {};
   private createPromise: Promise<AirwallexCardElements> | null = null;
 
-  private listeners = new Map<ElementType, Map<Payment.SplitElementEventCode, boolean>>();
-
-  // private created = false;
-
-  // async init() {
-  //   if (this.created) return;
-  //   this.created = true;
-  // }
-
   async createElements() {
 
     if (this.elements.cardNumber) {
@@ -110,18 +101,8 @@ class AirwallexManager {
   }
 
   on<EventCode extends Payment.SplitElementEventCode>(el: ElementType, event: EventCode, handler: Payment.SplitElementEventHandler<EventCode>) {
-    let eventMap = this.listeners.get(el);
-    
-    if (!eventMap) {
-      eventMap = new Map<Payment.SplitElementEventCode, boolean>([[event, false]]);
-      this.listeners.set(el, eventMap);
-    }
-    if(eventMap.get(event)) return; // 注册过就返回
 
     el.on(event, handler);
-
-    eventMap.set(event,true);
-    
   }
 
 
@@ -136,6 +117,8 @@ class AirwallexManager {
     });
 
     this.elements = {};
+    this.createPromise=null;
+
   }
 
   getElements() {

+ 62 - 76
src/lib/Airwallex/useAirwallexCard.ts

@@ -22,47 +22,47 @@ function airwallexCardReducer(state: AirwallexCardStateType, action: Partial<Air
     return {...newState};
 }
 
+const defaultAirwallexCardState: AirwallexCardStateType = {
+    cardNumberReady: false,
+    cvcReady: false,
+    expiryReady: false,
 
+    cardNumberValid: false,
+    cvcValid: false,
+    expiryValid: false,
+
+    cardNumberErrorMsg: "",
+    cvcErrorMsg: "",
+    expiryErrorMsg: "",
+};
 
 export function useAirwallexCard(
   enabled: boolean, 
   mountId: { cardNumber: string; cvc: string; expiry: string; },
   // callback: EventCallback
 ) {
-
-  const defaultAirwallexCardState: AirwallexCardStateType = {
-      cardNumberReady: false,
-      cvcReady: false,
-      expiryReady: false,
-
-      cardNumberValid: false,
-      cvcValid: false,
-      expiryValid: false,
-
-      cardNumberErrorMsg: "",
-      cvcErrorMsg: "",
-      expiryErrorMsg: "",
-  };
-  const [airwallexCardState, airwallexCardDispatch] = useReducer(airwallexCardReducer, defaultAirwallexCardState);
-  const readyAirwallexElement = useEffectEvent((event: any): void => {
-      console.log('----------------------------onReady---------------------');
-      const { type } = event.detail;
-      if (type === 'cardNumber') {
-          airwallexCardDispatch({
-              cardNumberReady: true
-          });
-      }
-      if (type === 'cvc') {
-          airwallexCardDispatch({
-              cvcReady: true
-          });
-      }
-      if (type === 'expiry') {
-          airwallexCardDispatch({
-              expiryReady: true
-          });
-      }
-  });
+  
+    
+    const [airwallexCardState, airwallexCardDispatch] = useReducer(airwallexCardReducer, defaultAirwallexCardState);
+    const readyAirwallexElement = useEffectEvent((event: any): void => {
+        console.log('----------------------------onReady---------------------');
+        const { type } = event.detail;
+        if (type === 'cardNumber') {
+            airwallexCardDispatch({
+                cardNumberReady: true
+            });
+        }
+        if (type === 'cvc') {
+            airwallexCardDispatch({
+                cvcReady: true
+            });
+        }
+        if (type === 'expiry') {
+            airwallexCardDispatch({
+                expiryReady: true
+            });
+        }
+    });
 
 
     const changeAirwallexElement = useEffectEvent((event: any) => {
@@ -143,34 +143,37 @@ export function useAirwallexCard(
   }>({});
 
   useEffect(() => {
+    console.log('enabled ------- ',enabled);
     if (!enabled) return;
 
     let destroyed = false;
 
     const init = async () => {
-      await airwallexInit();
-    //   await airwallexManager.init();
-
-      const els = await airwallexManager.createElements();
-      elementRef.current = els;
-console.log('useAirwallexCard +++++++++++++++++++++++++++++',destroyed);
-      if (destroyed) return;
-
-      airwallexManager.mount({
-        cardNumber: mountId.cardNumber,
-        cvc: mountId.cvc,
-        expiry: mountId.expiry
-      });
-
-      mountedRef.current = true;
-
-      // register events ONLY ONCE
-      bindEvents(els,{
-        focusCallback: focusAirwallexElement,
-        blurCallback: blurAirwallexElement, 
-        changeCallback: changeAirwallexElement, 
-        readyCallback: readyAirwallexElement
-      });
+        await airwallexInit();
+        //   await airwallexManager.init();
+
+        const els = await airwallexManager.createElements();
+        elementRef.current = els;
+            console.log('useAirwallexCard +++++++++++++++++++++++++++++',destroyed);
+        if (destroyed) return;
+        
+
+        airwallexManager.mount({
+            cardNumber: mountId.cardNumber,
+            cvc: mountId.cvc,
+            expiry: mountId.expiry
+        });
+
+        // register events ONLY ONCE
+        bindEvents(els,{
+            focusCallback: focusAirwallexElement,
+            blurCallback: blurAirwallexElement, 
+            changeCallback: changeAirwallexElement, 
+            readyCallback: readyAirwallexElement
+        });
+        mountedRef.current = true;
+
+      
     };
 
     init();
@@ -179,11 +182,11 @@ console.log('useAirwallexCard +++++++++++++++++++++++++++++',destroyed);
         console.log('useAirwallexCard ___________________________________',mountedRef.current)
       destroyed = true;
       if (mountedRef.current) {
-        airwallexManager.unmount();// 解除挂载
+        airwallexManager.destroy();// 解除挂载
         mountedRef.current = false;
       }
     };
-  }, [enabled]);
+  }, [enabled,mountId.cardNumber,mountId.cvc,mountId.expiry]);
 
 
 
@@ -212,21 +215,4 @@ function bindEvents(els: any,callback:EventCallback) {
   airwallexManager.on(expiry,"blur", blurCallback);
   airwallexManager.on(expiry,"change", changeCallback);
   airwallexManager.on(expiry,"ready", readyCallback);
-
-  // ⚠️ 关键:绑定只发生一次(manager内部防重复)
-//   cardNumber.on("focus", focusCallback);
-//   cardNumber.on("blur", blurCallback);
-//   cardNumber.on("change", changeCallback);
-//   cardNumber.on("ready", readyCallback);
-
-
-//   cvc.on("focus", focusCallback);
-//   cvc.on("blur", blurCallback);
-//   cvc.on("change", changeCallback);
-//   cvc.on("ready", readyCallback);
-
-//   expiry.on("focus", focusCallback);
-//   expiry.on("blur", blurCallback);
-//   expiry.on("change", changeCallback);
-//   expiry.on("ready", readyCallback);
 }

+ 10 - 13
src/utils/hooks/useCartDetail.ts

@@ -2,8 +2,8 @@
 
 import { useAppDispatch, useAppSelector } from "@/store/hooks";
 import { fetchCartDetail } from "@/store/slices/cart-slice";
-import { useCallback, useEffect } from "react";
-import { getCartToken } from "@/utils/getCartToken";
+import { useCallback } from "react";
+
 
 
 export function useCartDetail() {
@@ -12,20 +12,17 @@ export function useCartDetail() {
   const {cart, loading, error} = cartDetail;
 
   const getCartDetail = useCallback(async () => {
-    const token = getCartToken();
-    if (!token) {
-      return;
-    }
+
     dispatch(fetchCartDetail()); 
   }, [dispatch]);
 
-  // useCartDetail在组件中被调用时就会触发useEffect
-  // 初始化执行一次,获取购物车数据
-  useEffect(() => {
-    if (cart === null && !loading) {
-      getCartDetail();
-    }
-  }, [getCartDetail]);  
+  // // useCartDetail在组件中被调用时就会触发useEffect
+  // // 初始化执行一次,获取购物车数据
+  // useEffect(() => {
+  //   if (cart === null && !loading) {
+  //     getCartDetail();
+  //   }
+  // }, [getCartDetail]);  
 
   return {
     cartData: cart,