Переглянути джерело

根据eslint 修改代码

zhangzf 1 день тому
батько
коміт
266891b57d

+ 1 - 1
src/app/(public)/product/[...urlProduct]/page.tsx

@@ -3,7 +3,7 @@ import { Suspense } from "react";
 // import clsx from "clsx";
 // import type { ProductReviewList } from "@/types/products/productDetail";
 // import { getProductReviews } from "@utils/hooks/getProductReviews";
-import { restApiFetch } from "@utils/bagisto/index";
+// import { restApiFetch } from "@utils/bagisto/index";
 import {
   ProductDetailSkeleton,
   RelatedProductSkeleton,

+ 33 - 19
src/app/(public)/product/_components/SwitchButton.tsx

@@ -49,7 +49,7 @@ export default function SwitchButton({
   questionList,
   questionTotal,
 }: ReviewQuestionTabProps) {
-    const [uuid, setUuidId] = useState<string>('');
+    // const [uuid, setUuidId] = useState<string>('');
   // 自己通过接口拿到,不再由父组件传入
   const [reviewList, setReviewList] = useState<any[]>([]);
   const [reviewTotal, setReviewTotal] = useState<number>(0);
@@ -63,31 +63,45 @@ export default function SwitchButton({
     }
     return id;
   };
-    // 2. 封装评论请求函数
+  // 组件顶层,只生成一次uuid
+const [clientUuid] = useState(() => getUuId());
+  useEffect(() => {
+  if (!productId) return;
+  // 1. 请求中断控制器,组件卸载时取消网络请求,防止卸载后执行setState
+  const abortCtrl = new AbortController();
+  const signal = abortCtrl.signal;
+
+  // uuid 只初始化生成一次,存ref,不需要触发渲染
+  
+  
   const fetchReviews = async () => {
-      if (!productId) return;
     try {
-      const id = getUuId();
-      setUuidId(id);
       const res = await clientFetch(
-        `/api/shop/products/${productId}/reviews?page=1&per_page=10&has_images=0&sort=all&client_id=${id}`
+        `/api/shop/products/${productId}/reviews?page=1&per_page=10&has_images=0&sort=all&client_id=${clientUuid}`,
+        { signal } // 绑定中断信号
       );
       console.log('res------------------------------ccc:',res);
-      
-      // 3. 处理接口返回数据,严格对齐子组件需要的格式
+
       if (res.data.success) {
-      setReviewList(res?.data?.data ?? []);
-      setReviewTotal(res?.pagination?.total ?? 0);
-      } 
-    }  catch (err) {
-      console.error("获取评论失败", err);
-    } finally {
-      
+        setReviewList(res?.data?.data ?? []);
+        setReviewTotal(res?.pagination?.total ?? 0);
+      }
+    } catch (err: any) {
+      // 手动取消的请求不需要打印报错
+      if (err.name !== "AbortError") {
+        console.error("获取评论失败", err);
+      }
     }
   };
-  useEffect(() => {
-    fetchReviews();
-  }, [productId]);
+
+  fetchReviews();
+
+  // useEffect清理函数:组件卸载,终止请求
+  return () => {
+    abortCtrl.abort();
+  };
+}, [productId]);
+
 
   // 切换状态:默认激活评论
   const [activeTab, setActiveTab] = useState<"review" | "question">("review");
@@ -186,7 +200,7 @@ export default function SwitchButton({
               onOpenBaseModal={openAllReviewModal}
               activeTab={activeModalTab}
               onChangeTab={onTabChange}
-              uuid={uuid}
+              uuid={clientUuid}
             />
           )
         ) : isEmptyQuestion ? (

+ 2 - 1
src/app/(public)/product/_components/review/ReviewDetail.tsx

@@ -11,7 +11,7 @@ import { isArray } from "@/utils/type-guards";
 import { Avatar } from "@heroui/avatar";
 // import { Tooltip } from "@heroui/tooltip";
 import clsx from "clsx";
-import React, { FC, useState, useEffect } from "react";
+import React, { FC, useState } from "react";
 import { ProductReviewNode } from "@/components/catalog/type";
 import ReviewModal from "./ReviewModal";
 // import { ReviewTabType } from "@/types/products/review";
@@ -114,6 +114,7 @@ const ReviewDetail: FC<ReviewDetailProps> = ({
         showToast("Like Success", "success");
       }
     } catch (err) {
+         console.log(err);
       //网络失败回滚
       setLocalLikeMap((prev) => ({
         ...prev,

+ 1 - 0
src/app/(public)/product/_components/review/ReviewModal.tsx

@@ -311,6 +311,7 @@ const ReviewModal: React.FC<ReviewModalProps> = React.memo(
           showToast("Like Success", "success");
         }
       } catch (err) {
+        console.log(err);
         //网络失败回滚
         setLocalLikeMap((prev) => ({
           ...prev,