[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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user