[251029] fix: UseReviews V2적용
🕐 커밋 시간: 2025. 10. 29. 17:02:12 📊 변경 통계: • 총 파일: 4개 • 추가: +120줄 • 삭제: -263줄 📝 수정된 파일: ~ com.twin.app.shoptime/src/actions/productActions.js ~ com.twin.app.shoptime/src/actions/searchActions.js ~ com.twin.app.shoptime/src/hooks/useReviews/useReviews.js ~ com.twin.app.shoptime/src/reducers/productReducer.js 🔧 주요 변경 내용: • 핵심 비즈니스 로직 개선 • 중간 규모 기능 개선 • 코드 정리 및 최적화 Performance: 코드 최적화로 성능 개선 기대
This commit is contained in:
@@ -86,69 +86,40 @@ export const getProductOption = createGetThunk({
|
||||
tag: 'getProductOption',
|
||||
});
|
||||
|
||||
// FP: 실제 API 응답에서 data 부분만 추출 (간소화)
|
||||
const extractReviewApiData = (apiResponse) => {
|
||||
try {
|
||||
// console.log("[UserReviews] 🔍 extractReviewApiData - 전체 API 응답 분석:", {
|
||||
// fullApiResponse: apiResponse,
|
||||
// hasData: !!(apiResponse && apiResponse.data),
|
||||
// retCode: apiResponse && apiResponse.retCode,
|
||||
// retMsg: apiResponse && apiResponse.retMsg,
|
||||
// responseKeys: apiResponse ? Object.keys(apiResponse) : [],
|
||||
// dataKeys: apiResponse && apiResponse.data ? Object.keys(apiResponse.data) : []
|
||||
// });
|
||||
|
||||
// 여러 가능한 데이터 경로 시도
|
||||
let apiData = null;
|
||||
|
||||
// 1. response.data.data (중첩 구조)
|
||||
if (apiResponse && apiResponse.data && apiResponse.data.data) {
|
||||
apiData = apiResponse.data.data;
|
||||
// console.log("[UserReviews] ✅ 데이터 경로 1: response.data.data 사용");
|
||||
}
|
||||
// 2. response.data (단일 구조)
|
||||
else if (
|
||||
apiResponse &&
|
||||
apiResponse.data &&
|
||||
(apiResponse.data.reviewList || apiResponse.data.reviewDetail)
|
||||
) {
|
||||
apiData = apiResponse.data;
|
||||
// console.log("[UserReviews] ✅ 데이터 경로 2: response.data 사용");
|
||||
}
|
||||
// 3. response 직접 (최상위)
|
||||
else if (apiResponse && (apiResponse.reviewList || apiResponse.reviewDetail)) {
|
||||
apiData = apiResponse;
|
||||
// console.log("[UserReviews] ✅ 데이터 경로 3: response 직접 사용");
|
||||
}
|
||||
|
||||
if (!apiData) {
|
||||
// console.warn("[UserReviews] ❌ 모든 데이터 경로에서 추출 실패:", {
|
||||
// hasResponseData: !!(apiResponse && apiResponse.data),
|
||||
// hasReviewList: !!(apiResponse && apiResponse.data && apiResponse.data.reviewList),
|
||||
// hasReviewDetail: !!(apiResponse && apiResponse.data && apiResponse.data.reviewDetail),
|
||||
// hasNestedData: !!(apiResponse && apiResponse.data && apiResponse.data.data),
|
||||
// fullResponse: apiResponse
|
||||
// });
|
||||
return null;
|
||||
}
|
||||
|
||||
// 추출된 데이터 검증
|
||||
/* console.log("[UserReviews] 📊 추출된 데이터 검증:", {
|
||||
hasReviewList: !!apiData.reviewList,
|
||||
hasReviewDetail: !!apiData.reviewDetail,
|
||||
reviewListLength: apiData.reviewList ? apiData.reviewList.length : 0,
|
||||
reviewDetailKeys: apiData.reviewDetail ? Object.keys(apiData.reviewDetail) : [],
|
||||
totRvwCnt: apiData.reviewDetail && apiData.reviewDetail.totRvwCnt,
|
||||
totRvwAvg: apiData.reviewDetail && apiData.reviewDetail.totRvwAvg,
|
||||
extractedData: apiData
|
||||
}); */
|
||||
|
||||
return apiData;
|
||||
} catch (error) {
|
||||
console.error('[UserReviews] ❌ extractReviewApiData 에러:', error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
// ==================== [V1 API] 코멘트 처리: 기존 API 응답 추출 함수 (더 이상 사용하지 않음) ====================
|
||||
// const extractReviewApiData = (apiResponse) => {
|
||||
// try {
|
||||
// // 여러 가능한 데이터 경로 시도
|
||||
// let apiData = null;
|
||||
//
|
||||
// // 1. response.data.data (중첩 구조)
|
||||
// if (apiResponse && apiResponse.data && apiResponse.data.data) {
|
||||
// apiData = apiResponse.data.data;
|
||||
// }
|
||||
// // 2. response.data (단일 구조)
|
||||
// else if (
|
||||
// apiResponse &&
|
||||
// apiResponse.data &&
|
||||
// (apiResponse.data.reviewList || apiResponse.data.reviewDetail)
|
||||
// ) {
|
||||
// apiData = apiResponse.data;
|
||||
// }
|
||||
// // 3. response 직접 (최상위)
|
||||
// else if (apiResponse && (apiResponse.reviewList || apiResponse.reviewDetail)) {
|
||||
// apiData = apiResponse;
|
||||
// }
|
||||
//
|
||||
// if (!apiData) {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// return apiData;
|
||||
// } catch (error) {
|
||||
// console.error('[UserReviews] ❌ extractReviewApiData 에러:', error);
|
||||
// return null;
|
||||
// }
|
||||
// };
|
||||
// ==================== [V1 API] 코멘트 처리 끝 ====================
|
||||
|
||||
// IF-LGSP-101용 API 응답에서 reviewList + reviewDetail 추출
|
||||
const extractReviewListApiData = (apiResponse) => {
|
||||
@@ -288,158 +259,32 @@ export const resetShowAllReviews = () => ({
|
||||
type: types.RESET_SHOW_ALL_REVIEWS,
|
||||
});
|
||||
|
||||
// ==================== [V1 API] 코멘트 처리: 기존 API 호출 함수 (더 이상 사용하지 않음 - getUserReviewList 사용) ====================
|
||||
// 상품별 유저 리뷰 리스트 조회 : IF-LGSP-0002
|
||||
export const getUserReviews = (requestParams) => (dispatch, getState) => {
|
||||
const { prdtId, patnrId } = requestParams;
|
||||
|
||||
// console.log("[UserReviews] 🚀 getUserReviews 액션 시작:", {
|
||||
// requestParams,
|
||||
// prdtId,
|
||||
// patnrId,
|
||||
// timestamp: new Date().toISOString()
|
||||
// });
|
||||
|
||||
// ==================== [기존 테스트 코드] 시작 - 랜덤 prdtId 사용 (주석 처리) ====================
|
||||
// 테스트용 prdtId 목록 - 실제 리뷰 데이터가 있는 상품들
|
||||
/* const testProductIds = [
|
||||
'LCE3010SB',
|
||||
'100QNED85AU',
|
||||
'14Z90Q-K.ARW3U1',
|
||||
'16Z90Q-K.AAC7U1',
|
||||
'24GN600-B',
|
||||
'50UT8000AUA',
|
||||
'A949KTMS',
|
||||
'AGF76631064',
|
||||
'C5323B0',
|
||||
'DLE3600V',
|
||||
];
|
||||
const randomIndex = Math.floor(Math.random() * testProductIds.length);
|
||||
const randomPrdtId = testProductIds[randomIndex];
|
||||
|
||||
// console.log("[UserReviews]-API 🎲 랜덤 prdtId 선택:", {
|
||||
// originalPrdtId: prdtId,
|
||||
// originalPatnrId: patnrId,
|
||||
// randomPrdtId: randomPrdtId,
|
||||
// fixedPatnrId: '9',
|
||||
// randomIndex: randomIndex,
|
||||
// testProductIds: testProductIds
|
||||
// });
|
||||
*/
|
||||
// ==================== [기존 테스트 코드] 끝 ====================
|
||||
|
||||
// TAxios 파라미터 준비 - 실제 prdtId와 patnrId 사용
|
||||
const params = { prdtId, patnrId };
|
||||
const body = {}; // GET이므로 빈 객체
|
||||
|
||||
// plat_cd 값 확인을 위한 httpHeader 로깅
|
||||
const currentState = getState();
|
||||
const httpHeader = currentState.common.httpHeader || {};
|
||||
// console.log("[UserReviews] <20> plat_cd 값 확인:", {
|
||||
// platCd: httpHeader.plat_cd,
|
||||
// fullHttpHeader: httpHeader,
|
||||
// hasHttpHeader: !!httpHeader,
|
||||
// httpHeaderKeys: Object.keys(httpHeader)
|
||||
// });
|
||||
|
||||
// console.log("[UserReviews]-API <20>📡 TAxios 호출 준비:", {
|
||||
// method: "get",
|
||||
// url: URLS.GET_USER_REVEIW,
|
||||
// params,
|
||||
// body,
|
||||
// prdtId: prdtId,
|
||||
// patnrId: patnrId,
|
||||
// platCd: httpHeader.plat_cd
|
||||
// });
|
||||
|
||||
const onSuccess = (response) => {
|
||||
// console.log('[UserReviews]-API ✅ API 성공 응답:', {
|
||||
// status: response.status,
|
||||
// statusText: response.statusText,
|
||||
// headers: response.headers,
|
||||
// retCode: response.data && response.data.retCode,
|
||||
// retMsg: response.data && response.data.retMsg,
|
||||
// hasData: !!(response.data && response.data.data),
|
||||
// fullResponse: response.data,
|
||||
// });
|
||||
|
||||
// ==================== [임시 테스트] 빈 리뷰 응답 시뮬레이션 - 코멘트 처리 ====================
|
||||
// 30% 확률로 리뷰 없는 상품 응답 반환 (테스트용)
|
||||
/* if (Math.random() < 0.3) {
|
||||
console.log("[UserReviews] 🚫 임시 테스트: 빈 리뷰 응답 반환");
|
||||
const emptyReviewData = {
|
||||
reviewList: [],
|
||||
reviewDetail: {
|
||||
totRvwCnt: 0,
|
||||
totRvwAvg: 0,
|
||||
avgRvwScr: 0
|
||||
}
|
||||
};
|
||||
dispatch({
|
||||
type: types.GET_USER_REVIEW,
|
||||
payload: { ...emptyReviewData, prdtId: prdtId }
|
||||
});
|
||||
console.log("[UserReviews] 📦 빈 리뷰 데이터 디스패치 완료:", emptyReviewData);
|
||||
return;
|
||||
} */
|
||||
// ==================== [임시 테스트] 끝 - 코멘트 처리 ====================
|
||||
|
||||
// if (response.data && response.data.data) {
|
||||
// console.log('[UserReviews] 📊 API 데이터 상세:', {
|
||||
// reviewListLength: response.data.data.reviewList ? response.data.data.reviewList.length : 0,
|
||||
// reviewDetail: response.data.data.reviewDetail,
|
||||
// reviewList_sample:
|
||||
// (response.data.data.reviewList && response.data.data.reviewList[0]) || 'empty',
|
||||
// totRvwCnt: response.data.data.reviewDetail && response.data.data.reviewDetail.totRvwCnt,
|
||||
// totRvwAvg: response.data.data.reviewDetail && response.data.data.reviewDetail.totRvwAvg,
|
||||
// });
|
||||
// }
|
||||
|
||||
// 실제 API 응답에서 data 부분 추출
|
||||
const apiData = extractReviewApiData(response.data);
|
||||
|
||||
if (apiData) {
|
||||
console.log('[UserReviews] ✅ 실제 API 데이터 사용');
|
||||
dispatch({
|
||||
type: types.GET_USER_REVIEW,
|
||||
payload: { ...apiData, prdtId: prdtId }, // 원래 prdtId로 저장 (UI에서 사용)
|
||||
});
|
||||
console.log('[UserReviews] 📦 실제 API 데이터 디스패치 완료:', apiData);
|
||||
} else {
|
||||
console.log('[UserReviews] ⚠️ API 데이터 추출 실패');
|
||||
// Mock 데이터 사용 비활성화
|
||||
// const mockData = createMockReviewData();
|
||||
// dispatch({
|
||||
// type: types.GET_USER_REVIEW,
|
||||
// payload: { ...mockData, prdtId: prdtId }
|
||||
// });
|
||||
// console.log("[UserReviews] 📦 Mock 데이터 디스패치 완료:", mockData);
|
||||
}
|
||||
};
|
||||
|
||||
const onFail = (error) => {
|
||||
console.error('[UserReviews] ❌ API 실패:', {
|
||||
message: error.message,
|
||||
status: error.response && error.response.status,
|
||||
statusText: error.response && error.response.statusText,
|
||||
responseData: error.response && error.response.data,
|
||||
requestParams: requestParams,
|
||||
url: URLS.GET_USER_REVEIW,
|
||||
fullError: error,
|
||||
});
|
||||
|
||||
console.log('[UserReviews] 🔄 API 실패 - Mock 데이터 사용 비활성화');
|
||||
// Mock 데이터 사용 비활성화
|
||||
// const mockData = createMockReviewData();
|
||||
// dispatch({
|
||||
// type: types.GET_USER_REVIEW,
|
||||
// payload: { ...mockData, prdtId: prdtId }
|
||||
// });
|
||||
// console.log("[UserReviews] 📦 Mock 데이터 디스패치 완료 (API 실패):", mockData);
|
||||
};
|
||||
|
||||
// console.log("[UserReviews]-API 🔗 TAxios 호출 실행 중...");
|
||||
TAxios(dispatch, getState, 'get', URLS.GET_USER_REVEIW, params, body, onSuccess, onFail);
|
||||
};
|
||||
// export const getUserReviews = (requestParams) => (dispatch, getState) => {
|
||||
// const { prdtId, patnrId } = requestParams;
|
||||
// const params = { prdtId, patnrId };
|
||||
// const body = {};
|
||||
// const currentState = getState();
|
||||
// const httpHeader = currentState.common.httpHeader || {};
|
||||
//
|
||||
// const onSuccess = (response) => {
|
||||
// const apiData = extractReviewApiData(response.data);
|
||||
// if (apiData) {
|
||||
// dispatch({
|
||||
// type: types.GET_USER_REVIEW,
|
||||
// payload: { ...apiData, prdtId: prdtId },
|
||||
// });
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// const onFail = (error) => {
|
||||
// // API 실패 처리
|
||||
// };
|
||||
//
|
||||
// TAxios(dispatch, getState, 'get', URLS.GET_USER_REVEIW, params, body, onSuccess, onFail);
|
||||
// };
|
||||
// ==================== [V1 API] 코멘트 처리 끝 ====================
|
||||
|
||||
export const getProductOptionId = (id) => (dispatch) => {
|
||||
dispatch({ type: types.GET_PRODUCT_OPTION_ID, payload: id });
|
||||
|
||||
@@ -178,16 +178,23 @@ export const getShopperHouseSearch =
|
||||
return;
|
||||
}
|
||||
|
||||
// 📥 [VoiceInput] API 응답 성공 로그
|
||||
// 📥 [ShopperHouseAPI] API 응답 성공 로그
|
||||
const resultData = response.data.data.result;
|
||||
const results = resultData.results || [];
|
||||
const receivedSearchId = results.length > 0 ? results[0].searchId : null;
|
||||
const relativeQueries = results.length > 0 ? results[0].relativeQueries : null;
|
||||
|
||||
console.log('[VoiceInput] 📥 API 응답 성공');
|
||||
console.log('[VoiceInput] ├─ searchId:', receivedSearchId || '(없음)');
|
||||
console.log('[VoiceInput] ├─ 결과 수:', results.length);
|
||||
console.log('[VoiceInput] └─ relativeQueries:', relativeQueries || '(없음)');
|
||||
// 상품 개수 계산: results[0].docs 배열 길이
|
||||
const productCount = results.length > 0 && results[0].docs ? results[0].docs.length : 0;
|
||||
|
||||
const elapsedTime = ((new Date().getTime() - currentSearchKey) / 1000).toFixed(2);
|
||||
|
||||
console.log('*[ShopperHouseAPI] ✅ onSuccess - API 응답 성공');
|
||||
console.log('*[ShopperHouseAPI] ├─ searchId:', receivedSearchId === null ? '(NULL)' : receivedSearchId);
|
||||
console.log('*[ShopperHouseAPI] ├─ 상품 개수:', productCount);
|
||||
console.log('*[ShopperHouseAPI] ├─ relativeQueries:', relativeQueries || '(없음)');
|
||||
console.log('*[ShopperHouseAPI] ├─ 소요 시간:', elapsedTime + '초');
|
||||
console.log('*[ShopperHouseAPI] └─ timestamp:', new Date().toISOString());
|
||||
|
||||
dispatch({
|
||||
type: types.GET_SHOPPERHOUSE_SEARCH,
|
||||
@@ -213,15 +220,15 @@ export const getShopperHouseSearch =
|
||||
|
||||
// ✅ TAxios 재인증 오류 필터링 (기존 방식 그대로 활용)
|
||||
if (retCode === 401) {
|
||||
console.log('[VoiceInput] ⚠️ Access Token 만료 - TAxios가 자동으로 재요청합니다');
|
||||
console.log('[VoiceInput] └─ TAxios가 자동으로 재인증하고 재시도합니다');
|
||||
console.log('*[ShopperHouseAPI] ⚠️ onFail - Access Token 만료 (401)');
|
||||
console.log('*[ShopperHouseAPI] └─ TAxios가 자동으로 재인증하고 재시도합니다');
|
||||
// 401 에러는 Redux에 저장하지 않음 (TAxios 자동 재시도 대기)
|
||||
return;
|
||||
}
|
||||
|
||||
if (retCode === 402 || retCode === 501) {
|
||||
console.log('[VoiceInput] ⚠️ RefreshToken 만료 - TAxios가 자동으로 재발급합니다');
|
||||
console.log('[VoiceInput] └─ TAxios가 자동으로 토큰 재발급하고 재시도합니다');
|
||||
console.log('*[ShopperHouseAPI] ⚠️ onFail - RefreshToken 만료 (' + retCode + ')');
|
||||
console.log('*[ShopperHouseAPI] └─ TAxios가 자동으로 토큰 재발급하고 재시도합니다');
|
||||
// 402/501 에러는 Redux에 저장하지 않음 (TAxios 자동 재시도 대기)
|
||||
return;
|
||||
}
|
||||
@@ -232,17 +239,19 @@ export const getShopperHouseSearch =
|
||||
errorMessage?.includes('Network Error') ||
|
||||
errorMessage?.includes('timeout')
|
||||
) {
|
||||
console.log('[VoiceInput] ⚠️ 일시적인 네트워크 오류 - 재시도 필요');
|
||||
console.log('[VoiceInput] └─ TAxios 큐에 의해 자동 재시도될 수 있습니다');
|
||||
console.log('*[ShopperHouseAPI] ⚠️ onFail - 일시적인 네트워크 오류');
|
||||
console.log('*[ShopperHouseAPI] ├─ status:', status);
|
||||
console.log('*[ShopperHouseAPI] └─ errorMessage:', errorMessage);
|
||||
// 일시적인 네트워크 오류는 Redux에 저장하지 않음
|
||||
return;
|
||||
}
|
||||
|
||||
// ✨ 그 외의 실제 API 오류들만 Redux에 저장
|
||||
console.log('[VoiceInput] 📥 실제 API 오류 발생 - Redux에 저장');
|
||||
console.log('[VoiceInput] ├─ retCode:', retCode);
|
||||
console.log('[VoiceInput] ├─ status:', status);
|
||||
console.log('[VoiceInput] └─ error:', errorMessage || JSON.stringify(error));
|
||||
console.log('*[ShopperHouseAPI] ❌ onFail - 실제 API 오류 발생');
|
||||
console.log('*[ShopperHouseAPI] ├─ retCode:', retCode);
|
||||
console.log('*[ShopperHouseAPI] ├─ status:', status);
|
||||
console.log('*[ShopperHouseAPI] ├─ errorMessage:', errorMessage);
|
||||
console.log('*[ShopperHouseAPI] └─ retMsg:', error?.data?.retMsg || '(없음)');
|
||||
|
||||
dispatch(
|
||||
setShopperHouseError({
|
||||
@@ -267,7 +276,10 @@ export const getShopperHouseSearch =
|
||||
if (searchId) {
|
||||
params.searchid = searchId;
|
||||
}
|
||||
console.log('[ShopperHouse] getShopperHouseSearch params: ', JSON.stringify(params));
|
||||
console.log('*[ShopperHouseAPI] getShopperHouseSearch params: ', JSON.stringify(params));
|
||||
console.log('*[ShopperHouseAPI] ├─ query:', query);
|
||||
console.log('*[ShopperHouseAPI] ├─ searchId:', searchId === null ? '(NULL)' : searchId);
|
||||
console.log('*[ShopperHouseAPI] └─ timestamp:', new Date().toISOString());
|
||||
|
||||
TAxios(dispatch, getState, 'post', URLS.GET_SHOPPERHOUSE_SEARCH, {}, params, onSuccess, onFail);
|
||||
};
|
||||
|
||||
@@ -100,18 +100,18 @@ const useReviews = (prdtId, patnrId, _deprecatedReviewVersion) => {
|
||||
const isCurrentProductLoaded = prdtId === loadedPrdtId;
|
||||
|
||||
// Redux 상태 선택 로그
|
||||
useEffect(() => {
|
||||
console.log('[useReviews] 🔍 Redux 상태 선택:', {
|
||||
reviewVersion,
|
||||
prdtId,
|
||||
patnrId,
|
||||
loadedPrdtId,
|
||||
isCurrentProductLoaded,
|
||||
selectedReduxState: reviewVersion === 1 ? 'reviewData' : 'reviewListData',
|
||||
hasReviewData: !!reviewData,
|
||||
reviewDataLength: reviewData?.reviewList?.length || 0
|
||||
});
|
||||
}, [reviewVersion, prdtId, patnrId, loadedPrdtId, isCurrentProductLoaded, reviewData]);
|
||||
// useEffect(() => {
|
||||
// console.log('[useReviews] 🔍 Redux 상태 선택:', {
|
||||
// reviewVersion,
|
||||
// prdtId,
|
||||
// patnrId,
|
||||
// loadedPrdtId,
|
||||
// isCurrentProductLoaded,
|
||||
// selectedReduxState: reviewVersion === 1 ? 'reviewData' : 'reviewListData',
|
||||
// hasReviewData: !!reviewData,
|
||||
// reviewDataLength: reviewData?.reviewList?.length || 0
|
||||
// });
|
||||
// }, [reviewVersion, prdtId, patnrId, loadedPrdtId, isCurrentProductLoaded, reviewData]);
|
||||
|
||||
// UserReviewPanel 전용 페이징 상태 (다른 컴포넌트에 영향 없음)
|
||||
const [userReviewPanelPage, setUserReviewPanelPage] = useState(0);
|
||||
@@ -130,12 +130,12 @@ const useReviews = (prdtId, patnrId, _deprecatedReviewVersion) => {
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
console.log('[useReviews] 📋 loadReviews 호출됨:', {
|
||||
prdtId,
|
||||
patnrId,
|
||||
reviewVersion,
|
||||
willCallApi: reviewVersion === 1 ? 'getUserReviews (v1)' : 'getUserReviewList (v2)'
|
||||
});
|
||||
// console.log('[useReviews] 📋 loadReviews 호출됨:', {
|
||||
// prdtId,
|
||||
// patnrId,
|
||||
// reviewVersion,
|
||||
// willCallApi: reviewVersion === 1 ? 'getUserReviews (v1)' : 'getUserReviewList (v2)'
|
||||
// });
|
||||
|
||||
try {
|
||||
if (reviewVersion === 1) {
|
||||
@@ -144,7 +144,7 @@ const useReviews = (prdtId, patnrId, _deprecatedReviewVersion) => {
|
||||
await dispatch(getUserReviews({ prdtId, patnrId }));
|
||||
} else {
|
||||
// 신 API 호출 (v2)
|
||||
console.log('[useReviews] 🔄 getUserReviewList 호출 중... (v2)');
|
||||
// console.log('[useReviews] 🔄 getUserReviewList 호출 중... (v2)');
|
||||
await dispatch(getUserReviewList({
|
||||
prdtId,
|
||||
patnrId,
|
||||
@@ -167,14 +167,14 @@ const useReviews = (prdtId, patnrId, _deprecatedReviewVersion) => {
|
||||
if (prdtId && patnrId) {
|
||||
const needsLoad = prdtId !== loadedPrdtId;
|
||||
|
||||
console.log('[useReviews] 🔄 로드 필요 여부 체크:', {
|
||||
prdtId,
|
||||
patnrId,
|
||||
loadedPrdtId,
|
||||
reviewVersion,
|
||||
needsLoad,
|
||||
reason: needsLoad ? 'prdtId가 변경됨' : '캐시된 데이터 사용'
|
||||
});
|
||||
// console.log('[useReviews] 🔄 로드 필요 여부 체크:', {
|
||||
// prdtId,
|
||||
// patnrId,
|
||||
// loadedPrdtId,
|
||||
// reviewVersion,
|
||||
// needsLoad,
|
||||
// reason: needsLoad ? 'prdtId가 변경됨' : '캐시된 데이터 사용'
|
||||
// });
|
||||
|
||||
if (needsLoad) {
|
||||
// prdtId 변경 시 로딩 상태 즉시 설정으로 UI 깜빡임 방지
|
||||
|
||||
@@ -43,12 +43,12 @@ const handleProductOptionId = curry((state, action) =>
|
||||
);
|
||||
|
||||
// 유저 리뷰 데이터 핸들러 (v1 - 기존 API)
|
||||
const handleUserReview = curry((state, action) => {
|
||||
const reviewData = get('payload', action);
|
||||
const prdtId = get(['payload', 'prdtId'], action);
|
||||
// const handleUserReview = curry((state, action) => {
|
||||
// const reviewData = get('payload', action);
|
||||
// const prdtId = get(['payload', 'prdtId'], action);
|
||||
|
||||
return set('reviewData', reviewData, set('loadedPrdtId', prdtId, state));
|
||||
});
|
||||
// return set('reviewData', reviewData, set('loadedPrdtId', prdtId, state));
|
||||
// });
|
||||
|
||||
// 유저 리뷰 리스트 데이터 핸들러 (v2 - 신 API)
|
||||
const handleUserReviewList = curry((state, action) => {
|
||||
@@ -86,7 +86,7 @@ const handlers = {
|
||||
[types.GET_VIDEO_INDECATOR_FOCUS]: handleVideoIndicatorFocus,
|
||||
[types.CLEAR_PRODUCT_DETAIL]: handleClearProductDetail,
|
||||
[types.GET_PRODUCT_OPTION_ID]: handleProductOptionId,
|
||||
[types.GET_USER_REVIEW]: handleUserReview,
|
||||
// [types.GET_USER_REVIEW]: handleUserReview,
|
||||
[types.GET_USER_REVIEW_LIST]: handleUserReviewList,
|
||||
[types.TOGGLE_SHOW_ALL_REVIEWS]: handleToggleShowAllReviews,
|
||||
[types.RESET_SHOW_ALL_REVIEWS]: handleResetShowAllReviews,
|
||||
|
||||
Reference in New Issue
Block a user