[251210] fix: DetailPanel,ProductAllSection API최적화-2

🕐 커밋 시간: 2025. 12. 10. 17:30:18

📊 변경 통계:
  • 총 파일: 1개
  • 추가: +85줄
  • 삭제: -52줄

📝 수정된 파일:
  ~ com.twin.app.shoptime/src/views/DetailPanel/ProductAllSection/ProductAllSection.jsx

🔧 주요 변경 내용:
  • 소규모 기능 개선
  • 코드 정리 및 최적화
This commit is contained in:
2025-12-10 17:30:18 +09:00
parent 4fe3c94b1e
commit cbdf1b89f8

View File

@@ -274,7 +274,6 @@ export default function ProductAllSection({
// const [currentHeight, setCurrentHeight] = useState(0);
//하단부분까지 갔을때 체크용
const [documentHeight, setDocumentHeight] = useState(0);
const [isBottom, setIsBottom] = useState(false);
//qr코드 노출용
@@ -283,6 +282,8 @@ export default function ProductAllSection({
// sendLogGNB용 entryMenu
const entryMenuRef = useRef(null);
const lastProductDetailLogKeyRef = useRef(null);
const lastGnbLogKeyRef = useRef(null);
// 출처 정보 통합 (향후 확장성 대비)
// YouMayLike 상품이 아닐 경우 fromPanel을 초기화하여 오기 방지
@@ -298,6 +299,7 @@ export default function ProductAllSection({
// 모든 timeout/timer를 추적하기 위한 ref
const timersRef = useRef([]);
const contentHeightRef = useRef(0);
// handleScrollToImages의 timeout을 추적하기 위한 ref
const scrollToImagesTimeoutRef = useRef(null);
@@ -733,6 +735,7 @@ export default function ProductAllSection({
// sendLogGNB 로깅 - Source의 DetailPanel 컴포넌트들과 동일한 패턴
useEffect(() => {
if (!productData?.prdtId) return;
if (!entryMenuRef.current) entryMenuRef.current = nowMenu;
// BUY NOW 버튼 활성화 상태에 따른 메뉴 결정 (Source SingleProduct vs UnableProduct 패턴)
@@ -754,8 +757,22 @@ export default function ProductAllSection({
? `${baseMenu}/${Config.LOG_MENU.DETAIL_PAGE_YOU_MAY_LIKE}`
: baseMenu;
const logKey = `${productData?.patnrId || ''}-${productData?.prdtId || ''}`;
if (lastGnbLogKeyRef.current === logKey) {
return;
}
lastGnbLogKeyRef.current = logKey;
dispatch(sendLogGNB(menu));
}, [isBillingProductVisible, isGroupProductVisible, isTravelProductVisible, fromPanel?.fromYouMayLike]);
}, [
isBillingProductVisible,
isGroupProductVisible,
isTravelProductVisible,
fromPanel?.fromYouMayLike,
productData?.patnrId,
productData?.prdtId,
nowMenu,
]);
// sendLogGNB 전송 후 플래그 초기화 (1회 사용 후 비활성화)
useEffect(() => {
@@ -774,7 +791,24 @@ export default function ProductAllSection({
// sendLogProductDetail 로깅 - Source의 productData 변경 감지와 동일한 패턴
useEffect(() => {
if (productData && Object.keys(productData).length > 0) {
if (!productData || Object.keys(productData).length === 0) {
return;
}
const logTpNo = isTravelProductVisible
? Config.LOG_TP_NO.PRODUCT.TRAVEL_DETAIL
: isGroupProductVisible
? Config.LOG_TP_NO.PRODUCT.GROUP_DETAIL
: isBillingProductVisible
? Config.LOG_TP_NO.PRODUCT.BILLING_PRODUCT_DETAIL
: Config.LOG_TP_NO.PRODUCT.PRODUCT_DETAIL;
const logKey = `${productData?.patnrId || ''}-${productData?.prdtId || ''}-${panelInfo?.linkTpCd || ''}-${logTpNo}`;
if (lastProductDetailLogKeyRef.current === logKey) {
return;
}
lastProductDetailLogKeyRef.current = logKey;
const params = {
befPrice: productData?.priceInfo?.split("|")[0],
curationId: productData?.curationId ?? "",
@@ -786,13 +820,7 @@ export default function ProductAllSection({
lgCatCd: productData?.catCd ?? "",
lgCatNm: productData?.catNm ?? "",
linkTpCd: panelInfo?.linkTpCd ?? "",
logTpNo: isTravelProductVisible
? Config.LOG_TP_NO.PRODUCT.TRAVEL_DETAIL
: isGroupProductVisible
? Config.LOG_TP_NO.PRODUCT.GROUP_DETAIL
: isBillingProductVisible
? Config.LOG_TP_NO.PRODUCT.BILLING_PRODUCT_DETAIL
: Config.LOG_TP_NO.PRODUCT.PRODUCT_DETAIL,
logTpNo,
patncNm: productData?.patncNm ?? "",
patnrId: productData?.patnrId ?? "",
prdtId: productData?.prdtId ?? "",
@@ -803,8 +831,14 @@ export default function ProductAllSection({
};
dispatch(sendLogProductDetail(params));
}
}, [productData, panelInfo?.linkTpCd, isBillingProductVisible, isGroupProductVisible, isTravelProductVisible, dispatch]); // productData 변경 시 재실행
}, [
productData,
panelInfo?.linkTpCd,
isBillingProductVisible,
isGroupProductVisible,
isTravelProductVisible,
dispatch,
]); // productData 변경 시 재실행
// [251115] 주석 처리: MediaPanel에서 이미 포커스 이동을 처리하므로
// ProductAllSection의 자동 포커스는 포커스 탈취를 일으킬 수 있음
@@ -1246,6 +1280,13 @@ export default function ProductAllSection({
const prevScrollTopRef = useRef(0); // HomePanel 스타일 스크롤 위치 추적
const scrollExpandTimerRef = useRef(null); // 스크롤 확장 타이머
const mediaMinimizedRef = useRef(false);
const getTotalContentHeight = useCallback(() => {
const measuredHeight =
contentHeightRef.current ||
scrollContainerRef.current?.scrollHeight ||
0;
return measuredHeight + (youMayAlsoLikelRef.current?.scrollHeight || 0);
}, []);
const handleArrowClickAlternative = useCallback(() => {
dispatch(minimizeModalMedia());
@@ -1258,14 +1299,14 @@ export default function ProductAllSection({
animate: true,
});
// documentHeight를 활용하여 반복 계산 제거
const totalHeight = documentHeight + (youMayAlsoLikelRef.current?.scrollHeight || 0);
// 캐시된 콘텐츠 높이를 활용하여 반복 계산 최소화
const totalHeight = getTotalContentHeight();
const isAtBottom = scrollPositionRef.current + 1100 >= totalHeight;
if (isAtBottom) {
setIsBottom(isAtBottom);
}
}, [documentHeight, scrollTop, dispatch]);
}, [scrollTop, dispatch, getTotalContentHeight]);
const handleScroll = useCallback(
(e) => {
@@ -1276,12 +1317,12 @@ export default function ProductAllSection({
const prevScrollTop = prevScrollTopRef.current;
scrollPositionRef.current = currentScrollTop;
contentHeightRef.current = e?.scrollHeight || contentHeightRef.current || 0;
// 기존 bottom 체크 로직 유지
if (documentHeight) {
const isAtBottom =
scrollPositionRef.current + 944 >=
documentHeight + (youMayAlsoLikelRef.current?.scrollHeight || 0);
const totalHeight = getTotalContentHeight();
if (totalHeight) {
const isAtBottom = scrollPositionRef.current + 944 >= totalHeight;
if (isAtBottom !== isBottom) {
setIsBottom(isAtBottom);
}
@@ -1334,7 +1375,7 @@ export default function ProductAllSection({
}
// v2: onScrollStop에서 처리 (기존 로직 유지)
},
[documentHeight, isBottom, productVideoVersion, isVideoPlaying, dispatch]
[isBottom, productVideoVersion, isVideoPlaying, dispatch, getTotalContentHeight]
);
// 스크롤 멈추었을 때만 호출 (성능 최적화)
@@ -1342,10 +1383,10 @@ export default function ProductAllSection({
(e) => {
const currentScrollTop = e.scrollTop;
scrollPositionRef.current = currentScrollTop;
if (documentHeight) {
const isAtBottom =
currentScrollTop + 944 >=
documentHeight + (youMayAlsoLikelRef.current?.scrollHeight || 0);
contentHeightRef.current = e?.scrollHeight || contentHeightRef.current || 0;
const totalHeight = getTotalContentHeight();
if (totalHeight) {
const isAtBottom = currentScrollTop + 944 >= totalHeight;
if (isAtBottom !== isBottom) {
setIsBottom(isAtBottom);
}
@@ -1360,7 +1401,7 @@ export default function ProductAllSection({
return shouldMinimize;
});
},
[documentHeight]
[getTotalContentHeight]
);
useEffect(() => {
@@ -1385,14 +1426,6 @@ export default function ProductAllSection({
setActiveButton(null);
}, []);
useEffect(() => {
setDocumentHeight(
(productDetailRef.current?.scrollHeight || 0) +
(descriptionRef.current?.scrollHeight || 0) +
(reviewRef.current?.scrollHeight || 0)
);
}, [productDetailRef.current, descriptionRef.current, reviewRef.current]);
// 스크롤 위치에 따른 MediaPanel 제어 (비디오 재생 중에는 자동 제어 안함 - unmount 시에만 정리)
// useEffect(() => {
// console.log('📍 [ProductAllSection] useEffect 실행 - shouldMinimizeMedia:', shouldMinimizeMedia);