[250929] feat: YouMayLikeData관련 구조개선
This commit is contained in:
@@ -312,6 +312,12 @@ export const getMainYouMayLike =
|
|||||||
(dispatch, getState) => {
|
(dispatch, getState) => {
|
||||||
const onSuccess = (response) => {
|
const onSuccess = (response) => {
|
||||||
console.log("getMainYouMayLike onSuccess ", response.data);
|
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({
|
dispatch({
|
||||||
type: types.GET_YOUMAYLIKE,
|
type: types.GET_YOUMAYLIKE,
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const productData = useSelector((state) => state.main.productData);
|
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) =>
|
const isLoading = useSelector((state) =>
|
||||||
fp.pipe(() => state, fp.get("common.appStatus.showLoadingPanel.show"))()
|
fp.pipe(() => state, fp.get("common.appStatus.showLoadingPanel.show"))()
|
||||||
);
|
);
|
||||||
@@ -336,95 +338,85 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const shouldLoadRecommendations = fp.pipe(() => lgCatCd, fp.isNotEmpty)();
|
const shouldLoadRecommendations = fp.pipe(() => lgCatCd, fp.isNotEmpty)();
|
||||||
|
|
||||||
if (shouldLoadRecommendations) {
|
console.log('[YouMayLike] API 호출 체크:', {
|
||||||
dispatch(
|
lgCatCd,
|
||||||
getMainYouMayLike({
|
shouldLoadRecommendations,
|
||||||
lgCatCd: lgCatCd,
|
panelInfo_curationId: panelInfo?.curationId,
|
||||||
exclCurationId: panelCurationId,
|
panelInfo_patnrId: panelInfo?.patnrId,
|
||||||
exclPatnrId: panelPatnrId,
|
panelInfo_prdtId: panelInfo?.prdtId,
|
||||||
exclPrdtId: panelPrdtId,
|
// 비교용 - 제거 예정
|
||||||
})
|
old_panelCurationId: panelCurationId,
|
||||||
);
|
old_panelPatnrId: panelPatnrId,
|
||||||
}
|
old_panelPrdtId: panelPrdtId
|
||||||
}, [panelCurationId, panelPatnrId, panelPrdtId, lgCatCd]);
|
});
|
||||||
|
|
||||||
// FP 방식으로 카테고리 규칙 헬퍼 함수들 (curry 적용)
|
if (shouldLoadRecommendations) {
|
||||||
const categoryHelpers = useMemo(
|
const apiParams = {
|
||||||
() => ({
|
lgCatCd: lgCatCd,
|
||||||
createCategoryRule: fp.curry((conditionFn, extractFn, data) =>
|
exclCurationId: panelInfo?.curationId,
|
||||||
conditionFn(data) ? extractFn(data) : null
|
exclPatnrId: panelInfo?.patnrId,
|
||||||
),
|
exclPrdtId: panelInfo?.prdtId,
|
||||||
hasProductWithoutCuration: fp.curry(
|
};
|
||||||
(panelCurationId, productData) =>
|
console.log('[YouMayLike] getMainYouMayLike API 호출 중...', {
|
||||||
fp.isNotNil(productData) && fp.isNil(panelCurationId)
|
apiParams,
|
||||||
),
|
currentProduct: {
|
||||||
hasThemeWithPaymentCondition: fp.curry(
|
patnrId: panelInfo?.patnrId,
|
||||||
(panelCurationId, themeProductInfo) => {
|
prdtId: panelInfo?.prdtId,
|
||||||
const hasThemeProduct = fp.isNotNil(themeProductInfo);
|
curationId: panelInfo?.curationId
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
),
|
});
|
||||||
}),
|
dispatch(getMainYouMayLike(apiParams));
|
||||||
[]
|
} else {
|
||||||
);
|
console.log('[YouMayLike] API 호출하지 않음 - lgCatCd가 비어있음');
|
||||||
|
}
|
||||||
|
}, [panelInfo?.curationId, panelInfo?.patnrId, panelInfo?.prdtId, lgCatCd]);
|
||||||
|
|
||||||
const getlgCatCd = useCallback(() => {
|
const getlgCatCd = useCallback(() => {
|
||||||
// FP 방식으로 카테고리 코드 결정 - curry 적용으로 더 함수형 개선
|
// DetailPanel.backup.jsx와 완전히 동일한 로직
|
||||||
const categoryRules = [
|
if (productData && !panelInfo?.curationId) {
|
||||||
// 일반 상품 규칙 (curry 활용)
|
console.log('[YouMayLike] lgCatCd 설정 (일반상품):', productData.catCd);
|
||||||
() =>
|
setLgCatCd(productData.catCd);
|
||||||
categoryHelpers.createCategoryRule(
|
} else if (
|
||||||
categoryHelpers.hasProductWithoutCuration(panelCurationId),
|
themeProductInfos &&
|
||||||
(data) => fp.pipe(() => data, fp.get("catCd"))(),
|
themeProductInfos[selectedIndex]?.pmtSuptYn === "N" &&
|
||||||
productData
|
panelInfo?.curationId
|
||||||
),
|
) {
|
||||||
|
const themeCatCd = themeProductInfos[selectedIndex]?.catCd;
|
||||||
// 테마 상품 규칙 (curry 활용)
|
console.log('[YouMayLike] lgCatCd 설정 (테마상품):', themeCatCd);
|
||||||
() =>
|
setLgCatCd(themeCatCd);
|
||||||
categoryHelpers.createCategoryRule(
|
} else {
|
||||||
categoryHelpers.hasThemeWithPaymentCondition(panelCurationId),
|
console.log('[YouMayLike] lgCatCd 설정 (빈값):', {
|
||||||
(data) => fp.pipe(() => data, fp.get("catCd"))(),
|
hasProductData: !!productData,
|
||||||
themeProductInfo
|
panelCurationId: panelInfo?.curationId,
|
||||||
),
|
hasThemeProductInfos: !!themeProductInfos,
|
||||||
];
|
selectedIndex,
|
||||||
|
themeProductPmtSuptYn: themeProductInfos?.[selectedIndex]?.pmtSuptYn
|
||||||
// 첫 번째로 매칭되는 규칙의 결과 사용 (curry의 reduce 활용)
|
});
|
||||||
const categoryCode = fp.reduce(
|
setLgCatCd("");
|
||||||
(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();
|
|
||||||
}
|
}
|
||||||
}, [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에서 호출하세요.
|
// - 순수 유틸로 빌드/업서트 함수 작성 후, 적절한 useEffect에서 호출하세요.
|
||||||
@@ -646,6 +638,14 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
|
|||||||
}
|
}
|
||||||
}, [getProductType, productData, themeData, panelType]);
|
}, [getProductType, productData, themeData, panelType]);
|
||||||
|
|
||||||
|
// themeProductInfo 업데이트 - selectedIndex 변경 시마다 실행
|
||||||
|
useEffect(() => {
|
||||||
|
if (themeData?.productInfos && selectedIndex !== undefined) {
|
||||||
|
const themeProduct = themeData.productInfos[selectedIndex];
|
||||||
|
setThemeProductInfo(themeProduct);
|
||||||
|
}
|
||||||
|
}, [themeData, selectedIndex]);
|
||||||
|
|
||||||
const imageUrl = useMemo(
|
const imageUrl = useMemo(
|
||||||
() => fp.pipe(() => productData, fp.get("thumbnailUrl960"))(),
|
() => fp.pipe(() => productData, fp.get("thumbnailUrl960"))(),
|
||||||
[productData]
|
[productData]
|
||||||
@@ -791,6 +791,7 @@ export default function DetailPanel({ panelInfo, isOnTop, spotlightId }) {
|
|||||||
themeProductInfo={themeProductInfo}
|
themeProductInfo={themeProductInfo}
|
||||||
onReady={handleProductAllSectionReady}
|
onReady={handleProductAllSectionReady}
|
||||||
isOnRender={renderStates.canRender}
|
isOnRender={renderStates.canRender}
|
||||||
|
youmaylikeData={youmaylikeData}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ export default function ProductAllSection({
|
|||||||
themeProductInfo,
|
themeProductInfo,
|
||||||
onReady,
|
onReady,
|
||||||
isOnRender,
|
isOnRender,
|
||||||
|
youmaylikeData,
|
||||||
}) {
|
}) {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
@@ -211,10 +212,20 @@ export default function ProductAllSection({
|
|||||||
hasReviews, // 리뷰 존재 여부 플래그 추가
|
hasReviews, // 리뷰 존재 여부 플래그 추가
|
||||||
} = useReviews(productData.prdtId, panelInfo && panelInfo.patnrId);
|
} = useReviews(productData.prdtId, panelInfo && panelInfo.patnrId);
|
||||||
|
|
||||||
// YouMayAlsoLike 데이터 확인
|
// YouMayAlsoLike 데이터 확인 - props로 받은 데이터 사용
|
||||||
const youmaylikeProductData = useSelector((state) => state.main.youmaylikeData);
|
const youmaylikeProductData = youmaylikeData;
|
||||||
const hasYouMayAlsoLike = youmaylikeProductData && youmaylikeProductData.length > 0;
|
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 초기화
|
// ProductAllSection 마운트 시 showAllReviews 초기화
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('[ProductAllSection] Component mounted - resetting showAllReviews to false');
|
console.log('[ProductAllSection] Component mounted - resetting showAllReviews to false');
|
||||||
@@ -607,6 +618,15 @@ export default function ProductAllSection({
|
|||||||
{$L('YOU MAY ALSO LIKE')}
|
{$L('YOU MAY ALSO LIKE')}
|
||||||
</TButton>
|
</TButton>
|
||||||
)}
|
)}
|
||||||
|
{/* YouMayLike 버튼 렌더링 상태 로그 */}
|
||||||
|
{(() => {
|
||||||
|
console.log('[YouMayLike] 버튼 렌더링 체크:', {
|
||||||
|
hasYouMayAlsoLike,
|
||||||
|
shouldRenderButton: hasYouMayAlsoLike,
|
||||||
|
youmaylikeDataLength: youmaylikeProductData?.length || 0
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
})()}
|
||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
{panelInfo && panelInfo && panelInfo.type === 'theme' && !openThemeItemOverlay && (
|
{panelInfo && panelInfo && panelInfo.type === 'theme' && !openThemeItemOverlay && (
|
||||||
@@ -714,6 +734,14 @@ export default function ProductAllSection({
|
|||||||
<div ref={youMayAlsoLikelRef}>
|
<div ref={youMayAlsoLikelRef}>
|
||||||
<div id="scroll-marker-you-may-also-like" className={css.scrollMarker}></div>
|
<div id="scroll-marker-you-may-also-like" className={css.scrollMarker}></div>
|
||||||
<div id="you-may-also-like-section">
|
<div id="you-may-also-like-section">
|
||||||
|
{(() => {
|
||||||
|
console.log('[YouMayLike] YouMayAlsoLike 컴포넌트 렌더링:', {
|
||||||
|
productInfo: productData,
|
||||||
|
panelInfo,
|
||||||
|
hasData: !!youmaylikeProductData
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
})()}
|
||||||
<YouMayAlsoLike
|
<YouMayAlsoLike
|
||||||
productInfo={productData}
|
productInfo={productData}
|
||||||
panelInfo={panelInfo}
|
panelInfo={panelInfo}
|
||||||
|
|||||||
@@ -42,11 +42,21 @@ export default function YouMayAlsoLike({ productInfo, panelInfo, onFocus, onBlur
|
|||||||
);
|
);
|
||||||
//노출 9개로 변경위한 처리건.
|
//노출 9개로 변경위한 처리건.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
console.log('[YouMayLike] YouMayAlsoLike 컴포넌트 - 데이터 처리:', {
|
||||||
|
originalData: youmaylikeProductData,
|
||||||
|
originalLength: youmaylikeProductData?.length || 0,
|
||||||
|
hasData: !!(youmaylikeProductData && youmaylikeProductData.length > 0)
|
||||||
|
});
|
||||||
|
|
||||||
if (youmaylikeProductData && youmaylikeProductData.length > 0) {
|
if (youmaylikeProductData && youmaylikeProductData.length > 0) {
|
||||||
setNewYoumaylikeProductData(
|
const processedData = youmaylikeProductData.slice(0, youmaylikeProductData.length - 1);
|
||||||
youmaylikeProductData.slice(0, youmaylikeProductData.length - 1)
|
console.log('[YouMayLike] 처리된 데이터 설정:', {
|
||||||
);
|
processedLength: processedData.length,
|
||||||
|
processedData
|
||||||
|
});
|
||||||
|
setNewYoumaylikeProductData(processedData);
|
||||||
} else {
|
} else {
|
||||||
|
console.log('[YouMayLike] 데이터 없음 - 빈 배열 설정');
|
||||||
setNewYoumaylikeProductData([]);
|
setNewYoumaylikeProductData([]);
|
||||||
}
|
}
|
||||||
}, [youmaylikeProductData]);
|
}, [youmaylikeProductData]);
|
||||||
@@ -87,6 +97,14 @@ export default function YouMayAlsoLike({ productInfo, panelInfo, onFocus, onBlur
|
|||||||
}
|
}
|
||||||
}, [onBlur]);
|
}, [onBlur]);
|
||||||
|
|
||||||
|
// 렌더링 시점 로그
|
||||||
|
console.log('[YouMayLike] YouMayAlsoLike 렌더링:', {
|
||||||
|
newYoumaylikeProductData,
|
||||||
|
hasData: !!(newYoumaylikeProductData && newYoumaylikeProductData.length > 0),
|
||||||
|
dataLength: newYoumaylikeProductData?.length || 0,
|
||||||
|
willRender: !!(newYoumaylikeProductData && newYoumaylikeProductData.length > 0)
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{newYoumaylikeProductData && newYoumaylikeProductData.length > 0 && (
|
{newYoumaylikeProductData && newYoumaylikeProductData.length > 0 && (
|
||||||
|
|||||||
Reference in New Issue
Block a user