[251024] [251025] feat: SearchResults.new.v2.jsx 추가상품 포커스 이동 해결

This commit is contained in:
2025-10-24 22:39:33 +00:00
parent 2838e4b8ec
commit 25f25a157a
2 changed files with 52 additions and 9 deletions

View File

@@ -788,6 +788,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
shopperHouseInfo={undefined}
keywordClick={handleKeywordClick}
panelInfo={panelInfo}
cbChangePageRef={cbChangePageRef}
/>
) : (
<NoSearchResults />
@@ -808,6 +809,7 @@ export default function SearchPanel({ panelInfo, isOnTop, spotlightId }) {
keywordClick={handleKeywordClick}
panelInfo={panelInfo}
onRelativeQueryClick={handleHowAboutTheseQueryClick}
cbChangePageRef={cbChangePageRef}
/>
);

View File

@@ -74,6 +74,7 @@ const SearchResultsNew = ({
shopperHouseSearchId = null,
shopperHouseRelativeQueries = [],
onRelativeQueryClick,
cbChangePageRef,
}) => {
// ShopperHouse 데이터를 ItemCard 형식으로 변환
const convertedShopperHouseItems = useMemo(() => {
@@ -132,7 +133,9 @@ const SearchResultsNew = ({
const [styleChange, setStyleChange] = useState(false);
// filterMethods 빈 배열 캐싱으로 메모리 누수 방지
const filterMethods = useMemo(() => [], []);
const cbChangePageRef = useRef(null);
const localChangePageRef = useRef(null);
const effectiveChangePageRef = cbChangePageRef ?? localChangePageRef;
const [pendingFocusIndex, setPendingFocusIndex] = useState(null);
// HowAboutThese 모드 상태 관리
const [howAboutTheseMode, setHowAboutTheseMode] = useState(HOW_ABOUT_THESE_MODES.SMALL);
@@ -180,11 +183,11 @@ const SearchResultsNew = ({
setTab(index);
setVisibleCount(ITEMS_PER_PAGE); // 탭 변경시 표시 개수 리셋
if (cbChangePageRef.current) {
cbChangePageRef.current(0, false, false);
if (effectiveChangePageRef.current) {
effectiveChangePageRef.current(0, false, false);
}
},
[tab]
[tab, effectiveChangePageRef]
);
//필터선택
@@ -205,8 +208,8 @@ const SearchResultsNew = ({
// 맨 처음으로 이동 (위 버튼)
const upBtnClick = useCallback(() => {
if (cbChangePageRef.current) {
cbChangePageRef.current(0, true);
if (effectiveChangePageRef.current) {
effectiveChangePageRef.current(0, true);
}
const targetId =
@@ -229,10 +232,48 @@ const SearchResultsNew = ({
// 10개씩 추가 로드 (아래 버튼)
const downBtnClick = useCallback(() => {
if (hasMore) {
setVisibleCount((prev) => prev + ITEMS_PER_PAGE);
if (!hasMore) {
return;
}
}, [hasMore]);
const totalLength = currentData ? currentData.length : 0;
if (!totalLength) {
return;
}
setVisibleCount((prev) => {
const nextIndex = prev; // 새로 추가될 첫 번째 상품 인덱스
setPendingFocusIndex(nextIndex);
const nextCount = Math.min(prev + ITEMS_PER_PAGE, totalLength);
return nextCount;
});
}, [hasMore, currentData]);
useEffect(() => {
if (pendingFocusIndex === null) {
return;
}
const spotlightId = `searchItemContents${pendingFocusIndex}`;
const focusTimer = setTimeout(() => {
const targetElement = document.querySelector(
`[data-spotlight-id="${spotlightId}"]`
);
if (effectiveChangePageRef && effectiveChangePageRef.current) {
effectiveChangePageRef.current(spotlightId, true, true);
} else if (targetElement) {
targetElement.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
}
Spotlight.focus(spotlightId);
setPendingFocusIndex(null);
}, 150);
return () => clearTimeout(focusTimer);
}, [pendingFocusIndex, effectiveChangePageRef]);
// ProductCard 컴포넌트 - 의존성 최적화 및 안전한 이미지 사용
const renderItem = useCallback(