[251209] feat: NBCU-ShopByShow-4

🕐 커밋 시간: 2025. 12. 09. 16:19:54

📊 변경 통계:
  • 총 파일: 5개
  • 추가: +62줄
  • 삭제: -139줄

📝 수정된 파일:
  ~ com.twin.app.shoptime/src/hooks/useScrollTo.js
  ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShow.jsx
  ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShow.module.less

🗑️ 삭제된 파일:
  - com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowList.jsx
  - com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowList.module.less

🔧 주요 변경 내용:
  • 핵심 비즈니스 로직 개선
  • 소규모 기능 개선
  • 코드 정리 및 최적화

Performance: 코드 최적화로 성능 개선 기대
This commit is contained in:
2025-12-09 16:19:55 +09:00
parent 85c44cdd8b
commit a46d34b776
5 changed files with 62 additions and 139 deletions

View File

@@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useRef } from "react"; import React, { useCallback, useEffect, useRef } from "react";
export default function useScrollTo() { export default function useScrollTo({ skipAutoScrollTop = false } = {}) {
const scrollTo = useRef(); const scrollTo = useRef();
const scrollTop = useCallback( const scrollTop = useCallback(
@@ -23,8 +23,10 @@ export default function useScrollTo() {
}, []); }, []);
useEffect(() => { useEffect(() => {
if (!skipAutoScrollTop) {
scrollTop(); scrollTop();
}, []); }
}, [skipAutoScrollTop]);
return { getScrollTo, scrollLeft, scrollTop, scrollToRef: scrollTo }; return { getScrollTo, scrollLeft, scrollTop, scrollToRef: scrollTo };
} }

View File

@@ -1,12 +1,19 @@
import React, { memo, useCallback, useState } from "react"; import React, { memo, useCallback, useEffect, useRef, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { getBrandShopByShow } from "../../../actions/brandActions";
import { Job } from "@enact/core/util";
import Spotlight from "@enact/spotlight"; import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator"; import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import useScrollTo from "../../../hooks/useScrollTo";
import SectionTitle from "../../../components/SectionTitle/SectionTitle"; import SectionTitle from "../../../components/SectionTitle/SectionTitle";
import { $L } from "../../../utils/helperMethods"; import { $L } from "../../../utils/helperMethods";
import css from "./ShopByShow.module.less"; import css from "./ShopByShow.module.less";
import ShopByShowList from "./ShopByShowList/ShopByShowList"; import ShopByShowNav from "./ShopByShowList/ShopByShowNav/ShopByShowNav";
import ShopByShowContents from "./ShopByShowList/ShopByShowContents/ShopByShowContents";
const STRING_CONF = { const STRING_CONF = {
SHOP_BY_SHOW: "SHOP BY SHOW", SHOP_BY_SHOW: "SHOP BY SHOW",
@@ -28,6 +35,33 @@ const ShopByShow = ({
shelfTitle, shelfTitle,
}) => { }) => {
const [firstChk, setFirstChk] = useState(0); const [firstChk, setFirstChk] = useState(0);
const dispatch = useDispatch();
const { getScrollTo, scrollLeft } = useScrollTo({ skipAutoScrollTop: true });
const panelInfo = useSelector((state) => state.panels.panels[0]?.panelInfo);
const scrollLeftJob = useRef(new Job((func) => func(), 0));
const brandShopByShowClctInfos = brandShopByShowContsInfo?.brandShopByShowClctInfos || [];
const handleContsIdChange = useCallback((contsId) => {
dispatch(getBrandShopByShow({ patnrId: selectedPatnrId, contsId }));
}, [selectedPatnrId, dispatch]);
useEffect(() => {
if (panelInfo?.section !== "shop-by-show" || !panelInfo?.x) {
return;
}
const scrollLeftJobValue = scrollLeftJob.current;
const { x } = panelInfo;
scrollLeftJobValue.start(() => scrollLeft({ x }));
return () => scrollLeftJobValue.stop();
}, [panelInfo, scrollLeft]);
useEffect(() => {
scrollLeft();
}, [scrollLeft, selectedPatnrId]);
const _handleItemFocus = useCallback(() => { const _handleItemFocus = useCallback(() => {
if (handleItemFocus) handleItemFocus(spotlightId, shelfOrder); if (handleItemFocus) handleItemFocus(spotlightId, shelfOrder);
@@ -70,15 +104,27 @@ const ShopByShow = ({
data-title="shop-by-show" data-title="shop-by-show"
label="shop-by-show Heading 1" label="shop-by-show Heading 1"
/> />
<ShopByShowList <ShopByShowNav
brandShopByShowContsList={brandShopByShowContsList} brandShopByShowContsList={brandShopByShowContsList}
brandShopByShowContsInfo={brandShopByShowContsInfo} brandShopByShowContsInfo={brandShopByShowContsInfo}
handleItemFocus={_handleItemFocus} handleItemFocus={_handleItemFocus}
onContsIdChange={handleContsIdChange}
/>
{brandShopByShowClctInfos.map((collection, collIdx) => (
<ShopByShowContents
key={`${spotlightId}-${collIdx}`}
brandProductInfos={collection.brandProductInfos}
contentsIndex={collIdx}
handleItemFocus={_handleItemFocus}
clctNm={collection.clctNm}
clctImgUrl={collection.clctImgUrl}
patnrId={selectedPatnrId}
selectedPatnrId={selectedPatnrId} selectedPatnrId={selectedPatnrId}
spotlightId={spotlightId}
shelfOrder={shelfOrder} shelfOrder={shelfOrder}
shelfTitle={shelfTitle} shelfTitle={shelfTitle}
spotlightId={spotlightId}
/> />
))}
</Container> </Container>
); );
}; };

View File

@@ -9,4 +9,8 @@
margin-bottom: 24px; margin-bottom: 24px;
padding-left: 60px; padding-left: 60px;
} }
> nav {
margin-bottom: 30px;
}
} }

View File

@@ -1,116 +0,0 @@
import React, {
useCallback,
useEffect,
useRef,
useState,
} from 'react';
import {
useDispatch,
useSelector,
} from 'react-redux';
import { Job } from '@enact/core/util';
import SpotlightContainerDecorator
from '@enact/spotlight/SpotlightContainerDecorator';
import {
getContainerId,
setContainerLastFocusedElement,
} from '@enact/spotlight/src/container';
import { getBrandShopByShow } from '../../../../actions/brandActions';
import useScrollTo from '../../../../hooks/useScrollTo';
import css from './ShopByShowList.module.less';
import ShopByShowNav from './ShopByShowNav/ShopByShowNav';
import ShopByShowContents from './ShopByShowContents/ShopByShowContents';
const Container = SpotlightContainerDecorator(
{ leaveFor: { right: "" }, enterTo: "last-focused" },
"div"
);
export default function ShopByShowList({
brandShopByShowContsList,
brandShopByShowContsInfo,
handleItemFocus,
selectedPatnrId,
spotlightId,
shelfTitle,
shelfOrder,
}) {
const { getScrollTo, scrollLeft } = useScrollTo();
const dispatch = useDispatch();
const panelInfo = useSelector((state) => state.panels.panels[0]?.panelInfo);
const scrollLeftJob = useRef(new Job((func) => func(), 0));
const brandShopByShowClctInfos = brandShopByShowContsInfo?.brandShopByShowClctInfos || [];
useEffect(() => {
if (panelInfo?.section !== "shop-by-show" || !panelInfo?.x) {
return;
}
const scrollLeftJobValue = scrollLeftJob.current;
const { x } = panelInfo;
scrollLeftJobValue.start(() => scrollLeft({ x }));
return () => scrollLeftJobValue.stop();
}, [panelInfo, scrollLeft]);
useEffect(() => {
const containerId = "shop-by-show-list-id";
const container = document.getElementById(containerId);
if (container) {
const childrenId = getContainerId(container?.children[0].children[0]);
if (childrenId) {
setContainerLastFocusedElement(null, [containerId, childrenId]);
}
}
scrollLeft();
}, [scrollLeft, selectedPatnrId]);
const handleContsIdChange = useCallback((contsId) => {
dispatch(getBrandShopByShow({ patnrId: selectedPatnrId, contsId }));
}, [selectedPatnrId, dispatch]);
const _handleItemFocus = useCallback(() => {
if (handleItemFocus) {
handleItemFocus();
}
}, [handleItemFocus]);
return (
<Container
className={css.container}
id={"shop-by-show-list-id"}
spotlightId={"shop-by-show-list-id"}
>
<ShopByShowNav
brandShopByShowContsList={brandShopByShowContsList}
brandShopByShowContsInfo={brandShopByShowContsInfo}
handleItemFocus={_handleItemFocus}
onContsIdChange={handleContsIdChange}
/>
{brandShopByShowClctInfos.map((collection, collIdx) => (
<ShopByShowContents
key={`${spotlightId}-${collIdx}`}
brandProductInfos={collection.brandProductInfos}
contentsIndex={collIdx}
handleItemFocus={_handleItemFocus}
clctNm={collection.clctNm}
clctImgUrl={collection.clctImgUrl}
patnrId={selectedPatnrId}
selectedPatnrId={selectedPatnrId}
shelfOrder={shelfOrder}
shelfTitle={shelfTitle}
spotlightId={spotlightId}
/>
))}
</Container>
);
}

View File

@@ -1,13 +0,0 @@
@import "../../../../style/CommonStyle.module.less";
@import "../../../../style/utils.module.less";
.container {
display: flex;
flex-direction: column;
position: relative;
width: 100%;
> nav {
margin-bottom: 30px;
}
}