|
|
@@ -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 ? (
|