[250929] feat: YouMayLikeData관련 구조개선

This commit is contained in:
2025-09-29 18:31:38 +09:00
parent 4bece21b32
commit f35c00aca5
4 changed files with 142 additions and 89 deletions

View File

@@ -312,6 +312,12 @@ export const getMainYouMayLike =
(dispatch, getState) => {
const onSuccess = (response) => {
console.log("getMainYouMayLike onSuccess ", response.data);
console.log('[YouMayLike] API 응답 구조:', {
fullResponse: response.data,
dataField: response.data.data,
hasYoumaylike: !!(response.data.data && response.data.data.youmaylike),
youmaylikeLength: response.data.data?.youmaylike?.length || 0
});
dispatch({
type: types.GET_YOUMAYLIKE,

View File

@@ -55,6 +55,8 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
const dispatch = useDispatch();
const productData = useSelector((state) => state.main.productData);
const youmaylikeData = useSelector((state) => state.main.youmaylikeData);
const themeProductInfos = useSelector((state) => state.home.themeCurationDetailInfoData);
const isLoading = useSelector((state) =>
fp.pipe(() => state, fp.get("common.appStatus.showLoadingPanel.show"))()
);
@@ -336,95 +338,85 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
useEffect(() => {
const shouldLoadRecommendations = fp.pipe(() => lgCatCd, fp.isNotEmpty)();
if (shouldLoadRecommendations) {
dispatch(
getMainYouMayLike({
lgCatCd: lgCatCd,
exclCurationId: panelCurationId,
exclPatnrId: panelPatnrId,
exclPrdtId: panelPrdtId,
})
);
}
}, [panelCurationId, panelPatnrId, panelPrdtId, lgCatCd]);
console.log('[YouMayLike] API 호출 체크:', {
lgCatCd,
shouldLoadRecommendations,
panelInfo_curationId: panelInfo?.curationId,
panelInfo_patnrId: panelInfo?.patnrId,
panelInfo_prdtId: panelInfo?.prdtId,
// 비교용 - 제거 예정
old_panelCurationId: panelCurationId,
old_panelPatnrId: panelPatnrId,
old_panelPrdtId: panelPrdtId
});
// FP 방식으로 카테고리 규칙 헬퍼 함수들 (curry 적용)
const categoryHelpers = useMemo(
() => ({
createCategoryRule: fp.curry((conditionFn, extractFn, data) =>
conditionFn(data) ? extractFn(data) : null
),
hasProductWithoutCuration: fp.curry(
(panelCurationId, productData) =>
fp.isNotNil(productData) && fp.isNil(panelCurationId)
),
hasThemeWithPaymentCondition: fp.curry(
(panelCurationId, themeProductInfo) => {
const hasThemeProduct = fp.isNotNil(themeProductInfo);
const equalToN = fp.curry((expected, actual) => actual === expected)(
"N"
);
const isNoPayment = equalToN(
fp.pipe(() => themeProductInfo, fp.get("pmtSuptYn"))()
);
const hasCuration = fp.isNotNil(panelCurationId);
return hasThemeProduct && isNoPayment && hasCuration;
if (shouldLoadRecommendations) {
const apiParams = {
lgCatCd: lgCatCd,
exclCurationId: panelInfo?.curationId,
exclPatnrId: panelInfo?.patnrId,
exclPrdtId: panelInfo?.prdtId,
};
console.log('[YouMayLike] getMainYouMayLike API 호출 중...', {
apiParams,
currentProduct: {
patnrId: panelInfo?.patnrId,
prdtId: panelInfo?.prdtId,
curationId: panelInfo?.curationId
}
),
}),
[]
);
});
dispatch(getMainYouMayLike(apiParams));
} else {
console.log('[YouMayLike] API 호출하지 않음 - lgCatCd가 비어있음');
}
}, [panelInfo?.curationId, panelInfo?.patnrId, panelInfo?.prdtId, lgCatCd]);
const getlgCatCd = useCallback(() => {
// FP 방식으로 카테고리 코드 결정 - curry 적용으로 더 함수형 개선
const categoryRules = [
// 일반 상품 규칙 (curry 활용)
() =>
categoryHelpers.createCategoryRule(
categoryHelpers.hasProductWithoutCuration(panelCurationId),
(data) => fp.pipe(() => data, fp.get("catCd"))(),
productData
),
// 테마 상품 규칙 (curry 활용)
() =>
categoryHelpers.createCategoryRule(
categoryHelpers.hasThemeWithPaymentCondition(panelCurationId),
(data) => fp.pipe(() => data, fp.get("catCd"))(),
themeProductInfo
),
];
// 첫 번째로 매칭되는 규칙의 결과 사용 (curry의 reduce 활용)
const categoryCode = fp.reduce(
(result, value) => result || value || "",
"",
categoryRules.map((rule) => rule())
);
setLgCatCd(categoryCode);
}, [
productData,
selectedIndex,
panelCurationId,
themeProductInfo,
categoryHelpers,
]);
// FP 방식으로 카테고리 코드 업데이트 (메모리 누수 방지)
useEffect(() => {
const shouldUpdateCategory = fp.pipe(
() => ({ themeProductInfo, productData, panelInfo, selectedIndex }),
({ themeProductInfo, productData, panelInfo, selectedIndex }) =>
fp.isNotNil(themeProductInfo) ||
fp.isNotNil(productData) ||
fp.isNotNil(panelInfo)
)();
if (shouldUpdateCategory) {
getlgCatCd();
// DetailPanel.backup.jsx와 완전히 동일한 로직
if (productData && !panelInfo?.curationId) {
console.log('[YouMayLike] lgCatCd 설정 (일반상품):', productData.catCd);
setLgCatCd(productData.catCd);
} else if (
themeProductInfos &&
themeProductInfos[selectedIndex]?.pmtSuptYn === "N" &&
panelInfo?.curationId
) {
const themeCatCd = themeProductInfos[selectedIndex]?.catCd;
console.log('[YouMayLike] lgCatCd 설정 (테마상품):', themeCatCd);
setLgCatCd(themeCatCd);
} else {
console.log('[YouMayLike] lgCatCd 설정 (빈값):', {
hasProductData: !!productData,
panelCurationId: panelInfo?.curationId,
hasThemeProductInfos: !!themeProductInfos,
selectedIndex,
themeProductPmtSuptYn: themeProductInfos?.[selectedIndex]?.pmtSuptYn
});
setLgCatCd("");
}
}, [themeProductInfo, productData, panelInfo, selectedIndex]);
}, [productData, themeProductInfos, selectedIndex, panelInfo?.curationId]);
// 카테고리 코드 업데이트 - DetailPanel.backup.jsx와 동일한 의존성
useEffect(() => {
getlgCatCd();
}, [themeProductInfos, productData, panelInfo, selectedIndex, getlgCatCd]);
// lgCatCd 변경 추적 로그
useEffect(() => {
console.log('[YouMayLike] lgCatCd 변경됨:', {
lgCatCd,
willTriggerYouMayLike: !!lgCatCd
});
}, [lgCatCd]);
// youmaylikeData 변경 추적 로그
useEffect(() => {
console.log('[YouMayLike] DetailPanel - youmaylikeData 변경됨:', {
youmaylikeData,
hasData: !!(youmaylikeData && youmaylikeData.length > 0),
dataLength: youmaylikeData?.length || 0
});
}, [youmaylikeData]);
// 최근 본 상품 저장이 필요하면:
// - 순수 유틸로 빌드/업서트 함수 작성 후, 적절한 useEffect에서 호출하세요.
@@ -646,6 +638,14 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
}
}, [getProductType, productData, themeData, panelType]);
// themeProductInfo 업데이트 - selectedIndex 변경 시마다 실행
useEffect(() => {
if (themeData?.productInfos && selectedIndex !== undefined) {
const themeProduct = themeData.productInfos[selectedIndex];
setThemeProductInfo(themeProduct);
}
}, [themeData, selectedIndex]);
const imageUrl = useMemo(
() => fp.pipe(() => productData, fp.get("thumbnailUrl960"))(),
[productData]
@@ -791,6 +791,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
themeProductInfo={themeProductInfo}
onReady={handleProductAllSectionReady}
isOnRender={renderStates.canRender}
youmaylikeData={youmaylikeData}
/>
);
}

View File

@@ -145,6 +145,7 @@ export default function ProductAllSection({
themeProductInfo,
onReady,
isOnRender,
youmaylikeData,
}) {
const dispatch = useDispatch();
@@ -211,10 +212,20 @@ export default function ProductAllSection({
hasReviews, // 리뷰 존재 여부 플래그 추가
} = useReviews(productData.prdtId, panelInfo && panelInfo.patnrId);
// YouMayAlsoLike 데이터 확인
const youmaylikeProductData = useSelector((state) => state.main.youmaylikeData);
// YouMayAlsoLike 데이터 확인 - props로 받은 데이터 사용
const youmaylikeProductData = youmaylikeData;
const hasYouMayAlsoLike = youmaylikeProductData && youmaylikeProductData.length > 0;
// YouMayLike 데이터 디버깅
useEffect(() => {
console.log('[YouMayLike] ProductAllSection - 데이터 상태 (Props):', {
youmaylikeProductData,
hasYouMayAlsoLike,
dataLength: youmaylikeProductData?.length || 0,
productDataPrdtId: productData?.prdtId
});
}, [youmaylikeProductData, hasYouMayAlsoLike, productData]);
// ProductAllSection 마운트 시 showAllReviews 초기화
useEffect(() => {
console.log('[ProductAllSection] Component mounted - resetting showAllReviews to false');
@@ -607,6 +618,15 @@ export default function ProductAllSection({
{$L('YOU MAY ALSO LIKE')}
</TButton>
)}
{/* YouMayLike 버튼 렌더링 상태 로그 */}
{(() => {
console.log('[YouMayLike] 버튼 렌더링 체크:', {
hasYouMayAlsoLike,
shouldRenderButton: hasYouMayAlsoLike,
youmaylikeDataLength: youmaylikeProductData?.length || 0
});
return null;
})()}
</Container>
{panelInfo && panelInfo && panelInfo.type === 'theme' && !openThemeItemOverlay && (
@@ -714,6 +734,14 @@ export default function ProductAllSection({
<div ref={youMayAlsoLikelRef}>
<div id="scroll-marker-you-may-also-like" className={css.scrollMarker}></div>
<div id="you-may-also-like-section">
{(() => {
console.log('[YouMayLike] YouMayAlsoLike 컴포넌트 렌더링:', {
productInfo: productData,
panelInfo,
hasData: !!youmaylikeProductData
});
return null;
})()}
<YouMayAlsoLike
productInfo={productData}
panelInfo={panelInfo}

View File

@@ -42,11 +42,21 @@ export default function YouMayAlsoLike({ productInfo, panelInfo, onFocus, onBlur
);
//노출 9개로 변경위한 처리건.
useEffect(() => {
console.log('[YouMayLike] YouMayAlsoLike 컴포넌트 - 데이터 처리:', {
originalData: youmaylikeProductData,
originalLength: youmaylikeProductData?.length || 0,
hasData: !!(youmaylikeProductData && youmaylikeProductData.length > 0)
});
if (youmaylikeProductData && youmaylikeProductData.length > 0) {
setNewYoumaylikeProductData(
youmaylikeProductData.slice(0, youmaylikeProductData.length - 1)
);
const processedData = youmaylikeProductData.slice(0, youmaylikeProductData.length - 1);
console.log('[YouMayLike] 처리된 데이터 설정:', {
processedLength: processedData.length,
processedData
});
setNewYoumaylikeProductData(processedData);
} else {
console.log('[YouMayLike] 데이터 없음 - 빈 배열 설정');
setNewYoumaylikeProductData([]);
}
}, [youmaylikeProductData]);
@@ -87,6 +97,14 @@ export default function YouMayAlsoLike({ productInfo, panelInfo, onFocus, onBlur
}
}, [onBlur]);
// 렌더링 시점 로그
console.log('[YouMayLike] YouMayAlsoLike 렌더링:', {
newYoumaylikeProductData,
hasData: !!(newYoumaylikeProductData && newYoumaylikeProductData.length > 0),
dataLength: newYoumaylikeProductData?.length || 0,
willRender: !!(newYoumaylikeProductData && newYoumaylikeProductData.length > 0)
});
return (
<div>
{newYoumaylikeProductData && newYoumaylikeProductData.length > 0 && (