From df9eb68a982e4828c6152734a24e718d9abea840 Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Sun, 13 Aug 2023 17:10:38 +0900 Subject: [PATCH 01/15] =?UTF-8?q?feat:=20useSuspendedQuery=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.eslintrc.js | 1 + frontend/src/hooks/queries/index.ts | 1 + .../src/hooks/queries/useSuspendedQuery.ts | 95 +++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 frontend/src/hooks/queries/index.ts create mode 100644 frontend/src/hooks/queries/useSuspendedQuery.ts diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index 5ea0e3be4..963fcc6c8 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -102,6 +102,7 @@ module.exports = { 'import/no-unresolved': 'off', '@typescript-eslint/no-empty-function': 'off', '@typescript-eslint/ban-types': 'off', + 'import/export': 'off', }, settings: { 'import/resolver': { diff --git a/frontend/src/hooks/queries/index.ts b/frontend/src/hooks/queries/index.ts new file mode 100644 index 000000000..613609de5 --- /dev/null +++ b/frontend/src/hooks/queries/index.ts @@ -0,0 +1 @@ +export * from './useSuspendedQuery'; diff --git a/frontend/src/hooks/queries/useSuspendedQuery.ts b/frontend/src/hooks/queries/useSuspendedQuery.ts new file mode 100644 index 000000000..22466ddb9 --- /dev/null +++ b/frontend/src/hooks/queries/useSuspendedQuery.ts @@ -0,0 +1,95 @@ +import { useQuery } from '@tanstack/react-query'; +import type { QueryFunction, QueryKey, UseQueryOptions, UseQueryResult } from '@tanstack/react-query'; + +export type UseSuspendedQueryResult = Omit< + UseQueryResult, + 'error' | 'isLoading' | 'isError' | 'isFetching' | 'status' | 'data' +> & { data: TData; status: 'idle' | 'success' }; + +export type UseSuspendedQueryResultOnSuccess = UseSuspendedQueryResult & { + status: 'success'; + isSuccess: true; + isIdle: false; +}; + +export type UseSuspendedQueryResultOnIdle = UseSuspendedQueryResult & { + status: 'idle'; + isSuccess: false; + isIdle: true; +}; + +export type UseSuspendedQueryOptions< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey +> = Omit, 'suspense' | 'queryKey' | 'queryFn'>; + +export type UseSuspendedQueryOptionWithoutEnabled< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey +> = Omit, 'enabled'>; + +export function useSuspendedQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey +>( + queryKey: TQueryKey, + queryFn: QueryFunction, + options?: UseSuspendedQueryOptionWithoutEnabled +): UseSuspendedQueryResultOnSuccess; + +export function useSuspendedQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey +>( + queryKey: TQueryKey, + queryFn: QueryFunction, + options: UseSuspendedQueryOptionWithoutEnabled & { enabled?: true } +): UseSuspendedQueryResultOnSuccess; + +export function useSuspendedQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey +>( + queryKey: TQueryKey, + queryFn: QueryFunction, + options: UseSuspendedQueryOptionWithoutEnabled & { enabled: false } +): UseSuspendedQueryResultOnIdle; + +export function useSuspendedQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey +>( + queryKey: TQueryKey, + queryFn: QueryFunction, + options: UseSuspendedQueryOptionWithoutEnabled +): UseSuspendedQueryResultOnSuccess | UseSuspendedQueryResultOnIdle; + +export function useSuspendedQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey +>( + queryKey: TQueryKey, + queryFn: QueryFunction, + options?: UseSuspendedQueryOptions +) { + return useQuery({ + queryKey, + queryFn, + suspense: true, + ...options, + }) as UseSuspendedQueryResult; +} From 807751290ce81b62088e5c8ec694c1aef4daaf0d Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Sun, 13 Aug 2023 19:19:00 +0900 Subject: [PATCH 02/15] =?UTF-8?q?refactor:=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EC=BF=BC=EB=A6=AC=20useSuspendedQuery=EB=A1=9C=20=EC=A0=84?= =?UTF-8?q?=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/Common/CategoryMenu/CategoryMenu.tsx | 4 ++-- .../Product/ProductDetailItem/ProductDetailItem.tsx | 9 ++------- .../Review/ReviewRegisterForm/ReviewRegisterForm.tsx | 2 +- frontend/src/hooks/queries/product/useCategoryQuery.ts | 7 ++----- .../src/hooks/queries/product/useProductDetailQuery.ts | 7 ++----- 5 files changed, 9 insertions(+), 20 deletions(-) diff --git a/frontend/src/components/Common/CategoryMenu/CategoryMenu.tsx b/frontend/src/components/Common/CategoryMenu/CategoryMenu.tsx index 90a7d500c..b262b8acd 100644 --- a/frontend/src/components/Common/CategoryMenu/CategoryMenu.tsx +++ b/frontend/src/components/Common/CategoryMenu/CategoryMenu.tsx @@ -11,14 +11,14 @@ interface CategoryMenuProps { } const CategoryMenu = ({ menuVariant }: CategoryMenuProps) => { - const { data: categoryList } = useCategoryQuery(menuVariant); + const { data: categories } = useCategoryQuery(menuVariant); const { categoryIds, selectCategory } = useCategoryContext(); const currentCategoryId = categoryIds[menuVariant]; return ( - {categoryList?.map((menu) => { + {categories.map((menu) => { const isSelected = menu.id === currentCategoryId; return (
  • diff --git a/frontend/src/components/Product/ProductDetailItem/ProductDetailItem.tsx b/frontend/src/components/Product/ProductDetailItem/ProductDetailItem.tsx index 2c9620926..54058da90 100644 --- a/frontend/src/components/Product/ProductDetailItem/ProductDetailItem.tsx +++ b/frontend/src/components/Product/ProductDetailItem/ProductDetailItem.tsx @@ -10,16 +10,11 @@ interface ProductDetailItemProps { } const ProductDetailItem = ({ productId }: ProductDetailItemProps) => { - const theme = useTheme(); - const { data: productDetail } = useProductDetailQuery(productId); - - if (!productDetail) { - return null; - } - const { name, price, image, content, averageRating, tags, bookmark } = productDetail; + const theme = useTheme(); + return ( <> diff --git a/frontend/src/components/Review/ReviewRegisterForm/ReviewRegisterForm.tsx b/frontend/src/components/Review/ReviewRegisterForm/ReviewRegisterForm.tsx index 2d3f9f134..54892819d 100644 --- a/frontend/src/components/Review/ReviewRegisterForm/ReviewRegisterForm.tsx +++ b/frontend/src/components/Review/ReviewRegisterForm/ReviewRegisterForm.tsx @@ -67,7 +67,7 @@ const ReviewRegisterForm = ({ productId, targetRef, closeReviewDialog }: ReviewR - + diff --git a/frontend/src/hooks/queries/product/useCategoryQuery.ts b/frontend/src/hooks/queries/product/useCategoryQuery.ts index 55adee756..4b4c08c46 100644 --- a/frontend/src/hooks/queries/product/useCategoryQuery.ts +++ b/frontend/src/hooks/queries/product/useCategoryQuery.ts @@ -1,4 +1,4 @@ -import { useQuery } from '@tanstack/react-query'; +import { useSuspendedQuery } from '..'; import { categoryApi } from '@/apis'; import type { Category } from '@/types/common'; @@ -10,10 +10,7 @@ const fetchCategories = async (type: string) => { }; const useCategoryQuery = (type: string) => { - return useQuery({ - queryKey: ['categories', type], - queryFn: () => fetchCategories(type), - }); + return useSuspendedQuery(['categories', type], () => fetchCategories(type)); }; export default useCategoryQuery; diff --git a/frontend/src/hooks/queries/product/useProductDetailQuery.ts b/frontend/src/hooks/queries/product/useProductDetailQuery.ts index 46e0df3b2..b68028efc 100644 --- a/frontend/src/hooks/queries/product/useProductDetailQuery.ts +++ b/frontend/src/hooks/queries/product/useProductDetailQuery.ts @@ -1,4 +1,4 @@ -import { useQuery } from '@tanstack/react-query'; +import { useSuspendedQuery } from '..'; import { productApi } from '@/apis'; import type { ProductDetail } from '@/types/product'; @@ -10,10 +10,7 @@ const fetchProductDetail = async (productId: number) => { }; const useProductDetailQuery = (productId: number) => { - return useQuery({ - queryKey: ['productDetail', productId], - queryFn: () => fetchProductDetail(productId), - }); + return useSuspendedQuery(['productDetail', productId], () => fetchProductDetail(productId)); }; export default useProductDetailQuery; From 6090dfbe4abaed0805254c64c40a55da0f25839f Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Sun, 13 Aug 2023 19:24:59 +0900 Subject: [PATCH 03/15] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EC=BF=BC=EB=A6=AC=20=EC=84=9C=EC=8A=A4=ED=8E=9C=EB=94=94?= =?UTF-8?q?=EB=93=9C=20=EC=BF=BC=EB=A6=AC=EB=A1=9C=20=EC=A0=84=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Rank/ProductRankingList/ProductRankingList.tsx | 7 ++++--- .../Rank/ReviewRankingList/ReviewRankingList.tsx | 6 +++--- frontend/src/hooks/queries/rank/useProductRankingQuery.ts | 7 ++----- frontend/src/hooks/queries/rank/useReviewRankingQuery.ts | 7 ++----- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/frontend/src/components/Rank/ProductRankingList/ProductRankingList.tsx b/frontend/src/components/Rank/ProductRankingList/ProductRankingList.tsx index a1a8a2f19..08e37207b 100644 --- a/frontend/src/components/Rank/ProductRankingList/ProductRankingList.tsx +++ b/frontend/src/components/Rank/ProductRankingList/ProductRankingList.tsx @@ -5,17 +5,18 @@ import { ProductOverviewItem } from '@/components/Product'; import { PATH } from '@/constants/path'; import { useProductRankingQuery } from '@/hooks/queries/rank'; import displaySlice from '@/utils/displaySlice'; + interface ProductRankingListProps { isHomePage?: boolean; } -const ProductRankingList = ({ isHomePage }: ProductRankingListProps) => { +const ProductRankingList = ({ isHomePage = false }: ProductRankingListProps) => { const { data: productRankings } = useProductRankingQuery(); - const productsToDisplay = displaySlice(isHomePage, productRankings?.products, 3); + const productsToDisplay = displaySlice(isHomePage, productRankings.products, 3); return (
      - {productsToDisplay?.map(({ id, name, image, categoryType }, index) => ( + {productsToDisplay.map(({ id, name, image, categoryType }, index) => (
    • diff --git a/frontend/src/components/Rank/ReviewRankingList/ReviewRankingList.tsx b/frontend/src/components/Rank/ReviewRankingList/ReviewRankingList.tsx index 35039edce..2f3079cd7 100644 --- a/frontend/src/components/Rank/ReviewRankingList/ReviewRankingList.tsx +++ b/frontend/src/components/Rank/ReviewRankingList/ReviewRankingList.tsx @@ -9,13 +9,13 @@ interface ReviewRankingListProps { isHomePage?: boolean; } -const ReviewRankingList = ({ isHomePage }: ReviewRankingListProps) => { +const ReviewRankingList = ({ isHomePage = false }: ReviewRankingListProps) => { const { data: reviewRankings } = useReviewRankingQuery(); - const reviewsToDisplay = useDisplaySlice(isHomePage, reviewRankings?.reviews); + const reviewsToDisplay = useDisplaySlice(isHomePage, reviewRankings.reviews); return ( - {reviewsToDisplay?.map((reviewRanking) => ( + {reviewsToDisplay.map((reviewRanking) => (
    • diff --git a/frontend/src/hooks/queries/rank/useProductRankingQuery.ts b/frontend/src/hooks/queries/rank/useProductRankingQuery.ts index 2ef8bb74e..afc9b4f19 100644 --- a/frontend/src/hooks/queries/rank/useProductRankingQuery.ts +++ b/frontend/src/hooks/queries/rank/useProductRankingQuery.ts @@ -1,4 +1,4 @@ -import { useQuery } from '@tanstack/react-query'; +import { useSuspendedQuery } from '..'; import { rankApi } from '@/apis'; import type { ProductRankingResponse } from '@/types/response'; @@ -10,10 +10,7 @@ const fetchProductRanking = async () => { }; const useProductRankingQuery = () => { - return useQuery({ - queryKey: ['productRanking'], - queryFn: () => fetchProductRanking(), - }); + return useSuspendedQuery(['ranking', 'product'], () => fetchProductRanking()); }; export default useProductRankingQuery; diff --git a/frontend/src/hooks/queries/rank/useReviewRankingQuery.ts b/frontend/src/hooks/queries/rank/useReviewRankingQuery.ts index 30d37731d..edacfaaf8 100644 --- a/frontend/src/hooks/queries/rank/useReviewRankingQuery.ts +++ b/frontend/src/hooks/queries/rank/useReviewRankingQuery.ts @@ -1,4 +1,4 @@ -import { useQuery } from '@tanstack/react-query'; +import { useSuspendedQuery } from '..'; import { rankApi } from '@/apis'; import type { ReviewRankingResponse } from '@/types/response'; @@ -10,10 +10,7 @@ const fetchReviewRanking = async () => { }; const useReviewRankingQuery = () => { - return useQuery({ - queryKey: ['reviewRanking'], - queryFn: () => fetchReviewRanking(), - }); + return useSuspendedQuery(['ranking', 'review'], () => fetchReviewRanking()); }; export default useReviewRankingQuery; From 27326511781ebb011f1e75b3276f4a5048542d75 Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Sun, 13 Aug 2023 19:30:07 +0900 Subject: [PATCH 04/15] =?UTF-8?q?refactor:=20ProductOverviewItem=20prop=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Product/ProductOverviewItem/ProductOverviewItem.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/Product/ProductOverviewItem/ProductOverviewItem.tsx b/frontend/src/components/Product/ProductOverviewItem/ProductOverviewItem.tsx index 9441439b1..2bf72b2ca 100644 --- a/frontend/src/components/Product/ProductOverviewItem/ProductOverviewItem.tsx +++ b/frontend/src/components/Product/ProductOverviewItem/ProductOverviewItem.tsx @@ -4,18 +4,18 @@ import styled from 'styled-components'; import PreviewImage from '@/assets/characters.svg'; interface ProductOverviewItemProps { + name: string; + image: string | null; rank?: number; - name?: string; - image?: string; } -const ProductOverviewItem = ({ rank, name, image }: ProductOverviewItemProps) => { +const ProductOverviewItem = ({ name, image, rank }: ProductOverviewItemProps) => { return ( {rank ?? ''} - {image ? ( + {image !== null ? ( ) : ( From 6294e5f62d8869cb0210efad9be3f61051547105 Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Sun, 13 Aug 2023 19:47:04 +0900 Subject: [PATCH 05/15] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=ED=83=9C=EA=B7=B8=20=EC=84=9C=EC=8A=A4=ED=8C=AC=EB=94=94?= =?UTF-8?q?=EB=93=9C=20=EC=BF=BC=EB=A6=AC=EB=A1=9C=20=EC=A0=84=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/Review/ReviewTagList/ReviewTagList.tsx | 6 +----- frontend/src/hooks/queries/review/useReviewTagsQuery.ts | 7 ++----- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/frontend/src/components/Review/ReviewTagList/ReviewTagList.tsx b/frontend/src/components/Review/ReviewTagList/ReviewTagList.tsx index 763694d0d..c3f0cb49a 100644 --- a/frontend/src/components/Review/ReviewTagList/ReviewTagList.tsx +++ b/frontend/src/components/Review/ReviewTagList/ReviewTagList.tsx @@ -14,11 +14,7 @@ interface ReviewTagListProps { const ReviewTagList = ({ selectedTags }: ReviewTagListProps) => { const { data: tagsData } = useReviewTagsQuery(); - const { minDisplayedTags, canShowMore, showMoreTags } = useDisplayTag(tagsData ?? [], MIN_DISPLAYED_TAGS_LENGTH); - - if (!tagsData) { - return null; - } + const { minDisplayedTags, canShowMore, showMoreTags } = useDisplayTag(tagsData, MIN_DISPLAYED_TAGS_LENGTH); return ( diff --git a/frontend/src/hooks/queries/review/useReviewTagsQuery.ts b/frontend/src/hooks/queries/review/useReviewTagsQuery.ts index 0ddf05195..3ba2b3409 100644 --- a/frontend/src/hooks/queries/review/useReviewTagsQuery.ts +++ b/frontend/src/hooks/queries/review/useReviewTagsQuery.ts @@ -1,4 +1,4 @@ -import { useQuery } from '@tanstack/react-query'; +import { useSuspendedQuery } from '..'; import { tagApi } from '@/apis'; import type { ReviewTag } from '@/types/review'; @@ -10,10 +10,7 @@ const fetchReviewTags = async () => { }; const useReviewTagsQuery = () => { - return useQuery({ - queryKey: ['reviewTags'], - queryFn: () => fetchReviewTags(), - }); + return useSuspendedQuery(['review', 'tags'], () => fetchReviewTags()); }; export default useReviewTagsQuery; From 7904925b1794cbe0ec1e7592b434ec4098ae20f3 Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Mon, 14 Aug 2023 16:22:10 +0900 Subject: [PATCH 06/15] =?UTF-8?q?feat:=20useSuspendedInfiniteQuery=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/queries/index.ts | 1 + .../queries/useSuspendedInfiniteQuery.ts | 103 ++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 frontend/src/hooks/queries/useSuspendedInfiniteQuery.ts diff --git a/frontend/src/hooks/queries/index.ts b/frontend/src/hooks/queries/index.ts index 613609de5..2288777da 100644 --- a/frontend/src/hooks/queries/index.ts +++ b/frontend/src/hooks/queries/index.ts @@ -1 +1,2 @@ export * from './useSuspendedQuery'; +export * from './useSuspendedInfiniteQuery'; diff --git a/frontend/src/hooks/queries/useSuspendedInfiniteQuery.ts b/frontend/src/hooks/queries/useSuspendedInfiniteQuery.ts new file mode 100644 index 000000000..55ddc5c89 --- /dev/null +++ b/frontend/src/hooks/queries/useSuspendedInfiniteQuery.ts @@ -0,0 +1,103 @@ +import { + type InfiniteData, + type QueryKey, + type UseInfiniteQueryResult, + type UseInfiniteQueryOptions, + type QueryFunction, + useInfiniteQuery, +} from '@tanstack/react-query'; + +export type UseSuspendedInfiniteQueryResult = Omit< + UseInfiniteQueryResult, + 'error' | 'isLoading' | 'isError' | 'isFetching' | 'status' | 'data' +>; + +export type UseSuspendedInfiniteQueryResultOnSuccess = UseSuspendedInfiniteQueryResult & { + data: InfiniteData; + status: 'success'; + isSuccess: true; + isIdle: false; +}; + +export type UseSuspendedInfiniteQueryResultOnIdle = UseSuspendedInfiniteQueryResult & { + data: undefined; + status: 'idle'; + isSuccess: false; + isIdle: true; +}; + +export type UseSuspendedInfiniteQueryOptions< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey +> = Omit< + UseInfiniteQueryOptions, + 'suspense' | 'queryKey' | 'queryFn' +>; + +export type UseSuspendedInfiniteQueryOptionWithoutEnabled< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey +> = Omit, 'enabled'>; + +export function useSuspendedInfiniteQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey +>( + queryKey: TQueryKey, + queryFn: QueryFunction, + options?: UseSuspendedInfiniteQueryOptionWithoutEnabled +): UseSuspendedInfiniteQueryResultOnSuccess; + +export function useSuspendedInfiniteQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey +>( + queryKey: TQueryKey, + queryFn: QueryFunction, + options?: UseSuspendedInfiniteQueryOptionWithoutEnabled & { + enabled?: true; + } +): UseSuspendedInfiniteQueryResultOnSuccess; + +export function useSuspendedInfiniteQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey +>( + queryKey: TQueryKey, + queryFn: QueryFunction, + options: UseSuspendedInfiniteQueryOptionWithoutEnabled & { + enabled: false; + } +): UseSuspendedInfiniteQueryResultOnIdle; + +export function useSuspendedInfiniteQuery< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey +>( + queryKey: TQueryKey, + queryFn: QueryFunction, + options?: UseSuspendedInfiniteQueryOptions +) { + return useInfiniteQuery({ + queryKey, + queryFn, + suspense: true, + ...options, + }) as UseSuspendedInfiniteQueryResult; +} + +export default useSuspendedInfiniteQuery; From daf81bb3d519b3c71b2ca3cc0c36bc9c2d14f95f Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Mon, 14 Aug 2023 17:04:54 +0900 Subject: [PATCH 07/15] =?UTF-8?q?refactor:=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20useSuspendedInfiniteQuery=EB=A1=9C=20?= =?UTF-8?q?=EC=A0=84=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Review/ReviewList/ReviewList.tsx | 71 +++++++------------ .../product/useInfiniteProductReviewsQuery.ts | 22 +++--- frontend/src/mocks/handlers/reviewHandlers.ts | 5 +- frontend/src/pages/ProductDetailPage.tsx | 28 +++++--- 4 files changed, 61 insertions(+), 65 deletions(-) diff --git a/frontend/src/components/Review/ReviewList/ReviewList.tsx b/frontend/src/components/Review/ReviewList/ReviewList.tsx index dd64b78a1..a51bfb4b2 100644 --- a/frontend/src/components/Review/ReviewList/ReviewList.tsx +++ b/frontend/src/components/Review/ReviewList/ReviewList.tsx @@ -1,54 +1,53 @@ -import { Text, Link } from '@fun-eat/design-system'; import { useRef } from 'react'; -import { Link as RouterLink } from 'react-router-dom'; import styled from 'styled-components'; import ReviewItem from '../ReviewItem/ReviewItem'; -import { PATH } from '@/constants/path'; +import { Loading } from '@/components/Common'; import { useIntersectionObserver } from '@/hooks/common'; import { useInfiniteProductReviewsQuery } from '@/hooks/queries/product'; import type { SortOption } from '@/types/common'; -const LOGIN_ERROR_MESSAGE = - '로그인 해야 상품 리뷰를 볼 수 있어요.\n펀잇에 가입하고 편의점 상품의 리뷰를 확인해보세요 😊'; - interface ReviewListProps { productId: number; selectedOption: SortOption; } const ReviewList = ({ productId, selectedOption }: ReviewListProps) => { + const { fetchNextPage, hasNextPage, data, isFetchingNextPage } = useInfiniteProductReviewsQuery( + productId, + selectedOption.value + ); const scrollRef = useRef(null); - - const { fetchNextPage, hasNextPage, data, isError } = useInfiniteProductReviewsQuery(productId, selectedOption.value); useIntersectionObserver(fetchNextPage, scrollRef, hasNextPage); - if (isError) { - return ( - - - {LOGIN_ERROR_MESSAGE} - - - 로그인하러 가기 - - - ); - } + const reviews = data.pages.flatMap((page) => page.reviews); + + // TODO: 로그인 에러 페이지로 이동 예정. 다른 브랜치에서 작업중 + //if (isError) { + // return ( + // + // + // {LOGIN_ERROR_MESSAGE} + // + // + // 로그인하러 가기 + // + // + // ); + //} return ( <> - {data?.pages - .flatMap((page) => page.reviews) - .map((review) => ( -
    • - -
    • - ))} + {reviews.map((review) => ( +
    • + +
    • + ))}
      + {isFetchingNextPage && } ); }; @@ -60,21 +59,3 @@ const ReviewListContainer = styled.ul` flex-direction: column; row-gap: 60px; `; - -const ErrorContainer = styled.div` - display: flex; - flex-direction: column; - align-items: center; -`; - -const ErrorDescription = styled(Text)` - padding: 40px 0; - white-space: pre-line; - word-break: break-all; -`; - -const LoginLink = styled(Link)` - padding: 16px 24px; - border: 1px solid ${({ theme }) => theme.colors.gray4}; - border-radius: 8px; -`; diff --git a/frontend/src/hooks/queries/product/useInfiniteProductReviewsQuery.ts b/frontend/src/hooks/queries/product/useInfiniteProductReviewsQuery.ts index a2c85a848..9d6dc8a96 100644 --- a/frontend/src/hooks/queries/product/useInfiniteProductReviewsQuery.ts +++ b/frontend/src/hooks/queries/product/useInfiniteProductReviewsQuery.ts @@ -1,4 +1,4 @@ -import { useInfiniteQuery } from '@tanstack/react-query'; +import { useSuspendedInfiniteQuery } from '..'; import { productApi } from '@/apis'; import type { ProductReviewResponse } from '@/types/response'; @@ -15,15 +15,17 @@ const fetchProductReviews = async (pageParam: number, productId: number, sort: s }; const useInfiniteProductReviewsQuery = (productId: number, sort: string) => { - return useInfiniteQuery({ - queryKey: ['productReviews', productId, sort], - queryFn: ({ pageParam = 0 }) => fetchProductReviews(pageParam, productId, sort), - getNextPageParam: (prevResponse: ProductReviewResponse) => { - const isLast = prevResponse.page.lastPage; - const nextPage = prevResponse.page.requestPage + 1; - return isLast ? undefined : nextPage; - }, - }); + return useSuspendedInfiniteQuery( + ['productReviews', productId, sort], + ({ pageParam = 0 }) => fetchProductReviews(pageParam, productId, sort), + { + getNextPageParam: (prevResponse: ProductReviewResponse) => { + const isLast = prevResponse.page.lastPage; + const nextPage = prevResponse.page.requestPage + 1; + return isLast ? undefined : nextPage; + }, + } + ); }; export default useInfiniteProductReviewsQuery; diff --git a/frontend/src/mocks/handlers/reviewHandlers.ts b/frontend/src/mocks/handlers/reviewHandlers.ts index 31888ab30..52ab30eac 100644 --- a/frontend/src/mocks/handlers/reviewHandlers.ts +++ b/frontend/src/mocks/handlers/reviewHandlers.ts @@ -14,7 +14,7 @@ export const reviewHandlers = [ const page = Number(req.url.searchParams.get('page')); if (!mockSessionId) { - return res(ctx.status(403)); + return res(ctx.status(401)); } if (sortOptions === null) { @@ -36,7 +36,8 @@ export const reviewHandlers = [ return res( ctx.status(200), - ctx.json({ page: sortedReviews.page, reviews: sortedReviews.reviews.slice(page * 5, (page + 1) * 5) }) + ctx.json({ page: sortedReviews.page, reviews: sortedReviews.reviews }), + ctx.delay(1000) ); }), diff --git a/frontend/src/pages/ProductDetailPage.tsx b/frontend/src/pages/ProductDetailPage.tsx index 940f94e19..9013d20bf 100644 --- a/frontend/src/pages/ProductDetailPage.tsx +++ b/frontend/src/pages/ProductDetailPage.tsx @@ -1,9 +1,17 @@ import { BottomSheet, Button, Spacing, useBottomSheet } from '@fun-eat/design-system'; -import { useState, useRef } from 'react'; +import { useState, useRef, Suspense } from 'react'; import { useParams } from 'react-router-dom'; import styled from 'styled-components'; -import { SortButton, SortOptionList, TabMenu, ScrollButton } from '@/components/Common'; +import { + SortButton, + SortOptionList, + TabMenu, + ScrollButton, + Loading, + ErrorBoundary, + ErrorComponent, +} from '@/components/Common'; import { ProductDetailItem } from '@/components/Product'; import { ReviewList, ReviewRegisterForm } from '@/components/Review'; import { REVIEW_SORT_OPTIONS } from '@/constants'; @@ -36,12 +44,16 @@ const ProductDetailPage = () => { {/* 나중에 API 수정하면 이 부분도 같이 수정해주세요 */} - - - -
      - -
      + + }> + + + +
      + +
      +
      +
      Date: Mon, 14 Aug 2023 17:10:55 +0900 Subject: [PATCH 08/15] =?UTF-8?q?refactor:=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=20useSuspendedInfiniteQuery?= =?UTF-8?q?=EB=A1=9C=20=EC=A0=84=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Product/PBProductList/PBProductList.tsx | 6 ++--- .../Product/ProductList/ProductList.tsx | 4 ++-- .../product/useInfiniteProductsQuery.ts | 22 +++++++++++-------- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/frontend/src/components/Product/PBProductList/PBProductList.tsx b/frontend/src/components/Product/PBProductList/PBProductList.tsx index b76030c46..0c297c1cc 100644 --- a/frontend/src/components/Product/PBProductList/PBProductList.tsx +++ b/frontend/src/components/Product/PBProductList/PBProductList.tsx @@ -18,13 +18,13 @@ const PBProductList = ({ isHomePage }: PBProductListProps) => { const { categoryIds } = useCategoryContext(); const { data: pbProductListResponse } = useInfiniteProductsQuery(categoryIds.store); - const pbProductList = pbProductListResponse?.pages.flatMap((page) => page.products); - const pbProductsToDisplay = displaySlice(isHomePage, pbProductList, 10); + const pbProducts = pbProductListResponse.pages.flatMap((page) => page.products); + const pbProductsToDisplay = displaySlice(isHomePage, pbProducts, 10); return ( <> - {pbProductsToDisplay?.map((pbProduct) => ( + {pbProductsToDisplay.map((pbProduct) => (
    • diff --git a/frontend/src/components/Product/ProductList/ProductList.tsx b/frontend/src/components/Product/ProductList/ProductList.tsx index ddb651eab..63e2cbaac 100644 --- a/frontend/src/components/Product/ProductList/ProductList.tsx +++ b/frontend/src/components/Product/ProductList/ProductList.tsx @@ -27,7 +27,7 @@ const ProductList = ({ category, isHomePage, selectedOption }: ProductListProps) categoryIds[category], selectedOption?.value ?? 'reviewCount,desc' ); - const productList = data?.pages.flatMap((page) => page.products); + const productList = data.pages.flatMap((page) => page.products); const productsToDisplay = displaySlice(isHomePage, productList); useIntersectionObserver(fetchNextPage, scrollRef, hasNextPage); @@ -35,7 +35,7 @@ const ProductList = ({ category, isHomePage, selectedOption }: ProductListProps) return ( <> - {productsToDisplay?.map((product) => ( + {productsToDisplay.map((product) => (
    • diff --git a/frontend/src/hooks/queries/product/useInfiniteProductsQuery.ts b/frontend/src/hooks/queries/product/useInfiniteProductsQuery.ts index 1158b9ccc..681158ab6 100644 --- a/frontend/src/hooks/queries/product/useInfiniteProductsQuery.ts +++ b/frontend/src/hooks/queries/product/useInfiniteProductsQuery.ts @@ -1,5 +1,7 @@ import { useInfiniteQuery } from '@tanstack/react-query'; +import useSuspendedInfiniteQuery from '../useSuspendedInfiniteQuery'; + import { categoryApi } from '@/apis'; import type { CategoryProductResponse } from '@/types/response'; @@ -14,15 +16,17 @@ const fetchProducts = async (pageParam: number, categoryId: number, sort = 'revi }; const useInfiniteProductsQuery = (categoryId: number, sort = 'reviewCount,desc') => { - return useInfiniteQuery({ - queryKey: ['products', categoryId, sort], - queryFn: ({ pageParam = 0 }) => fetchProducts(pageParam, categoryId, sort), - getNextPageParam: (prevResponse: CategoryProductResponse) => { - const isLast = prevResponse.page.lastPage; - const nextPage = prevResponse.page.requestPage + 1; - return isLast ? undefined : nextPage; - }, - }); + return useSuspendedInfiniteQuery( + ['products', categoryId, sort], + ({ pageParam = 0 }) => fetchProducts(pageParam, categoryId, sort), + { + getNextPageParam: (prevResponse: CategoryProductResponse) => { + const isLast = prevResponse.page.lastPage; + const nextPage = prevResponse.page.requestPage + 1; + return isLast ? undefined : nextPage; + }, + } + ); }; export default useInfiniteProductsQuery; From 3d540e4d771ad6734e19f8e62cd50383b24c6cb8 Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Mon, 14 Aug 2023 17:15:01 +0900 Subject: [PATCH 09/15] =?UTF-8?q?refactor:=20=EA=BF=80=EC=A1=B0=ED=95=A9?= =?UTF-8?q?=20=EC=83=81=EC=84=B8=20useSuspendedQuery=EB=A1=9C=20=EC=A0=84?= =?UTF-8?q?=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/hooks/queries/product/useInfiniteProductsQuery.ts | 4 +--- frontend/src/hooks/queries/recipe/useRecipeDetailQuery.ts | 7 ++----- frontend/src/pages/RecipeDetailPage.tsx | 5 ----- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/frontend/src/hooks/queries/product/useInfiniteProductsQuery.ts b/frontend/src/hooks/queries/product/useInfiniteProductsQuery.ts index 681158ab6..0f4652569 100644 --- a/frontend/src/hooks/queries/product/useInfiniteProductsQuery.ts +++ b/frontend/src/hooks/queries/product/useInfiniteProductsQuery.ts @@ -1,6 +1,4 @@ -import { useInfiniteQuery } from '@tanstack/react-query'; - -import useSuspendedInfiniteQuery from '../useSuspendedInfiniteQuery'; +import { useSuspendedInfiniteQuery } from '..'; import { categoryApi } from '@/apis'; import type { CategoryProductResponse } from '@/types/response'; diff --git a/frontend/src/hooks/queries/recipe/useRecipeDetailQuery.ts b/frontend/src/hooks/queries/recipe/useRecipeDetailQuery.ts index 99ff7f150..8f8ad9c28 100644 --- a/frontend/src/hooks/queries/recipe/useRecipeDetailQuery.ts +++ b/frontend/src/hooks/queries/recipe/useRecipeDetailQuery.ts @@ -1,4 +1,4 @@ -import { useQuery } from '@tanstack/react-query'; +import { useSuspendedQuery } from '..'; import { recipeApi } from '@/apis'; import type { RecipeDetail } from '@/types/recipe'; @@ -10,10 +10,7 @@ const fetchRecipeDetail = async (recipeId: number) => { }; const useRecipeDetailQuery = (recipeId: number) => { - return useQuery({ - queryKey: ['recipeDetail', recipeId], - queryFn: () => fetchRecipeDetail(recipeId), - }); + return useSuspendedQuery(['recipeDetail', recipeId], () => fetchRecipeDetail(recipeId)); }; export default useRecipeDetailQuery; diff --git a/frontend/src/pages/RecipeDetailPage.tsx b/frontend/src/pages/RecipeDetailPage.tsx index 81d020b4a..baeeb286f 100644 --- a/frontend/src/pages/RecipeDetailPage.tsx +++ b/frontend/src/pages/RecipeDetailPage.tsx @@ -10,11 +10,6 @@ const RecipeDetailPage = () => { const { recipeId } = useParams(); const { data: recipeDetail } = useRecipeDetailQuery(Number(recipeId)); - - if (!recipeDetail) { - return null; - } - const { images, title, content, author, products, totalPrice, favoriteCount, favorite, createdAt } = recipeDetail; return ( From 8bb42e4b123bd1f59172ab549adc359e80ae0211 Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Mon, 14 Aug 2023 17:19:02 +0900 Subject: [PATCH 10/15] =?UTF-8?q?refactor:=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20useSuspendedInfiniteQuery=EB=A1=9C=20?= =?UTF-8?q?=EC=A0=84=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Search/RecommendList/RecommendList.tsx | 4 ---- .../Search/SearchedList/SearchedList.tsx | 4 ---- .../useInfiniteSearchedProductsQuery.ts | 23 ++++++++++--------- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/frontend/src/components/Search/RecommendList/RecommendList.tsx b/frontend/src/components/Search/RecommendList/RecommendList.tsx index 387d8612c..bc409fc40 100644 --- a/frontend/src/components/Search/RecommendList/RecommendList.tsx +++ b/frontend/src/components/Search/RecommendList/RecommendList.tsx @@ -17,10 +17,6 @@ const RecommendList = ({ searchQuery }: RecommendListProps) => { const scrollRef = useRef(null); useIntersectionObserver(fetchNextPage, scrollRef, hasNextPage); - if (!searchResponse) { - return null; - } - const products = searchResponse.pages .flatMap((page) => page.products) .map((product) => ({ diff --git a/frontend/src/components/Search/SearchedList/SearchedList.tsx b/frontend/src/components/Search/SearchedList/SearchedList.tsx index 1620f7be2..3b17ffe4a 100644 --- a/frontend/src/components/Search/SearchedList/SearchedList.tsx +++ b/frontend/src/components/Search/SearchedList/SearchedList.tsx @@ -17,10 +17,6 @@ const SearchedList = ({ searchQuery }: SearchedListProps) => { const scrollRef = useRef(null); useIntersectionObserver(fetchNextPage, scrollRef, hasNextPage); - if (!searchResponse) { - return null; - } - const products = searchResponse.pages.flatMap((page) => page.products); if (products.length === 0) { diff --git a/frontend/src/hooks/queries/search/useInfiniteSearchedProductsQuery.ts b/frontend/src/hooks/queries/search/useInfiniteSearchedProductsQuery.ts index 418778f5f..4ea8f1106 100644 --- a/frontend/src/hooks/queries/search/useInfiniteSearchedProductsQuery.ts +++ b/frontend/src/hooks/queries/search/useInfiniteSearchedProductsQuery.ts @@ -1,4 +1,4 @@ -import { useInfiniteQuery } from '@tanstack/react-query'; +import { useSuspendedInfiniteQuery } from '..'; import { searchApi } from '@/apis'; import type { SearchedProductResponse } from '@/types/response'; @@ -11,16 +11,17 @@ const fetchSearchedProducts = async (query: string, page: number) => { }; const useInfiniteSearchedProductsQuery = (query: string) => { - return useInfiniteQuery({ - queryKey: ['search', 'products', query], - queryFn: ({ pageParam = 0 }) => fetchSearchedProducts(query, pageParam), - getNextPageParam: (prevResponse: SearchedProductResponse) => { - const isLast = prevResponse.page.lastPage; - const nextPage = prevResponse.page.requestPage + 1; - return isLast ? undefined : nextPage; - }, - suspense: true, - }); + return useSuspendedInfiniteQuery( + ['search', 'products', query], + ({ pageParam = 0 }) => fetchSearchedProducts(query, pageParam), + { + getNextPageParam: (prevResponse: SearchedProductResponse) => { + const isLast = prevResponse.page.lastPage; + const nextPage = prevResponse.page.requestPage + 1; + return isLast ? undefined : nextPage; + }, + } + ); }; export default useInfiniteSearchedProductsQuery; From b52d5ad42a413c5b0f6afc6297a04a8912e88039 Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Mon, 14 Aug 2023 17:23:07 +0900 Subject: [PATCH 11/15] =?UTF-8?q?refactor:=20=EB=A9=A4=EB=B2=84=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20useSuspendedInfiniteQuery=EB=A1=9C=20?= =?UTF-8?q?=EC=A0=84=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Members/MemberReviewList/MemberReviewList.tsx | 6 +++--- .../hooks/queries/members/useInfiniteMemberReviewQuery.ts | 6 ++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/Members/MemberReviewList/MemberReviewList.tsx b/frontend/src/components/Members/MemberReviewList/MemberReviewList.tsx index e91aad3c1..dfaa25cda 100644 --- a/frontend/src/components/Members/MemberReviewList/MemberReviewList.tsx +++ b/frontend/src/components/Members/MemberReviewList/MemberReviewList.tsx @@ -15,12 +15,12 @@ const MemberReviewList = ({ isMemberPage = false }: MemberReviewListProps) => { const scrollRef = useRef(null); const { fetchNextPage, hasNextPage, data } = useInfiniteMemberReviewQuery(); - const memberReviews = data?.pages.flatMap((page) => page.reviews); + const memberReviews = data.pages.flatMap((page) => page.reviews); const reviewsToDisplay = useDisplaySlice(isMemberPage, memberReviews); useIntersectionObserver(fetchNextPage, scrollRef, hasNextPage); - const totalReviewCount = data?.pages.flatMap((page) => page.page.totalDataCount); + const totalReviewCount = data.pages.flatMap((page) => page.page.totalDataCount); return ( @@ -31,7 +31,7 @@ const MemberReviewList = ({ isMemberPage = false }: MemberReviewListProps) => { )} - {reviewsToDisplay?.map((reviewRanking) => ( + {reviewsToDisplay.map((reviewRanking) => (
    • diff --git a/frontend/src/hooks/queries/members/useInfiniteMemberReviewQuery.ts b/frontend/src/hooks/queries/members/useInfiniteMemberReviewQuery.ts index 8e8d19570..40e0e088e 100644 --- a/frontend/src/hooks/queries/members/useInfiniteMemberReviewQuery.ts +++ b/frontend/src/hooks/queries/members/useInfiniteMemberReviewQuery.ts @@ -1,4 +1,4 @@ -import { useInfiniteQuery } from '@tanstack/react-query'; +import { useSuspendedInfiniteQuery } from '..'; import { memberApi } from '@/apis'; import type { MemberReviewResponse } from '@/types/response'; @@ -10,9 +10,7 @@ const fetchMemberReview = async (pageParam: number) => { }; const useInfiniteMemberReviewQuery = () => { - return useInfiniteQuery({ - queryKey: ['member', 'reviews'], - queryFn: ({ pageParam = 0 }) => fetchMemberReview(pageParam), + return useSuspendedInfiniteQuery(['member', 'reviews'], ({ pageParam = 0 }) => fetchMemberReview(pageParam), { getNextPageParam: (prevResponse: MemberReviewResponse) => { const isLast = prevResponse.page.lastPage; const nextPage = prevResponse.page.requestPage + 1; From 91b18b90897c97b0a18afe27b0b655d9623765e1 Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Mon, 14 Aug 2023 17:34:41 +0900 Subject: [PATCH 12/15] =?UTF-8?q?refactor:=20=EC=98=B5=EC=85=94=EB=84=90?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/Product/ProductItem/ProductItem.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/components/Product/ProductItem/ProductItem.tsx b/frontend/src/components/Product/ProductItem/ProductItem.tsx index 9fef53963..b0608d950 100644 --- a/frontend/src/components/Product/ProductItem/ProductItem.tsx +++ b/frontend/src/components/Product/ProductItem/ProductItem.tsx @@ -4,6 +4,7 @@ import styled from 'styled-components'; import PreviewImage from '@/assets/characters.svg'; import { SvgIcon } from '@/components/Common'; import type { Product } from '@/types/product'; + interface ProductItemProps { product: Product; } From cd2ce6d1407903b5340b097acabd9646d3257ece Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Mon, 14 Aug 2023 17:49:21 +0900 Subject: [PATCH 13/15] =?UTF-8?q?style:=20=ED=83=80=EC=9E=85=20=EC=9E=84?= =?UTF-8?q?=ED=8F=AC=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/hooks/queries/useSuspendedInfiniteQuery.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/src/hooks/queries/useSuspendedInfiniteQuery.ts b/frontend/src/hooks/queries/useSuspendedInfiniteQuery.ts index 55ddc5c89..e9763cb5a 100644 --- a/frontend/src/hooks/queries/useSuspendedInfiniteQuery.ts +++ b/frontend/src/hooks/queries/useSuspendedInfiniteQuery.ts @@ -1,10 +1,10 @@ -import { - type InfiniteData, - type QueryKey, - type UseInfiniteQueryResult, - type UseInfiniteQueryOptions, - type QueryFunction, - useInfiniteQuery, +import { useInfiniteQuery } from '@tanstack/react-query'; +import type { + InfiniteData, + QueryKey, + UseInfiniteQueryResult, + UseInfiniteQueryOptions, + QueryFunction, } from '@tanstack/react-query'; export type UseSuspendedInfiniteQueryResult = Omit< From 3058b11a98d10f083e7e52094aadf551540c39ab Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Wed, 16 Aug 2023 11:30:48 +0900 Subject: [PATCH 14/15] =?UTF-8?q?refactor:=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=EC=BF=BC=EB=A6=AC=20useSuspendedInfiniteQuery=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Search/RecommendList/RecommendList.tsx | 4 ---- .../SearchResultList/SearchResultList.tsx | 4 ---- ...eInfiniteProductSearchAutocompleteQuery.ts | 23 ++++++++++--------- .../useInfiniteProductSearchResultsQuery.ts | 23 ++++++++++--------- 4 files changed, 24 insertions(+), 30 deletions(-) diff --git a/frontend/src/components/Search/RecommendList/RecommendList.tsx b/frontend/src/components/Search/RecommendList/RecommendList.tsx index 4ccc390e3..cbb53c212 100644 --- a/frontend/src/components/Search/RecommendList/RecommendList.tsx +++ b/frontend/src/components/Search/RecommendList/RecommendList.tsx @@ -17,10 +17,6 @@ const RecommendList = ({ searchQuery }: RecommendListProps) => { const scrollRef = useRef(null); useIntersectionObserver(fetchNextPage, scrollRef, hasNextPage); - if (!searchResponse) { - return null; - } - const products = searchResponse.pages.flatMap((page) => page.products); if (products.length === 0) { diff --git a/frontend/src/components/Search/SearchResultList/SearchResultList.tsx b/frontend/src/components/Search/SearchResultList/SearchResultList.tsx index 7cc9717ea..36108f719 100644 --- a/frontend/src/components/Search/SearchResultList/SearchResultList.tsx +++ b/frontend/src/components/Search/SearchResultList/SearchResultList.tsx @@ -17,10 +17,6 @@ const SearchResultList = ({ searchQuery }: SearchResultListProps) => { const scrollRef = useRef(null); useIntersectionObserver(fetchNextPage, scrollRef, hasNextPage); - if (!searchResponse) { - return null; - } - const products = searchResponse.pages.flatMap((page) => page.products); if (products.length === 0) { diff --git a/frontend/src/hooks/queries/search/useInfiniteProductSearchAutocompleteQuery.ts b/frontend/src/hooks/queries/search/useInfiniteProductSearchAutocompleteQuery.ts index e224c4116..492f3d96e 100644 --- a/frontend/src/hooks/queries/search/useInfiniteProductSearchAutocompleteQuery.ts +++ b/frontend/src/hooks/queries/search/useInfiniteProductSearchAutocompleteQuery.ts @@ -1,4 +1,4 @@ -import { useInfiniteQuery } from '@tanstack/react-query'; +import { useSuspendedInfiniteQuery } from '..'; import { searchApi } from '@/apis'; import type { ProductSearchAutocompleteResponse } from '@/types/response'; @@ -11,16 +11,17 @@ const fetchProductSearchAutocomplete = async (query: string, page: number) => { }; const useInfiniteProductSearchAutocompleteQuery = (query: string) => { - return useInfiniteQuery({ - queryKey: ['search', 'products', query], - queryFn: ({ pageParam = 0 }) => fetchProductSearchAutocomplete(query, pageParam), - getNextPageParam: (prevResponse: ProductSearchAutocompleteResponse) => { - const isLast = prevResponse.page.lastPage; - const nextPage = prevResponse.page.requestPage + 1; - return isLast ? undefined : nextPage; - }, - suspense: true, - }); + return useSuspendedInfiniteQuery( + ['search', 'products', query], + ({ pageParam = 0 }) => fetchProductSearchAutocomplete(query, pageParam), + { + getNextPageParam: (prevResponse: ProductSearchAutocompleteResponse) => { + const isLast = prevResponse.page.lastPage; + const nextPage = prevResponse.page.requestPage + 1; + return isLast ? undefined : nextPage; + }, + } + ); }; export default useInfiniteProductSearchAutocompleteQuery; diff --git a/frontend/src/hooks/queries/search/useInfiniteProductSearchResultsQuery.ts b/frontend/src/hooks/queries/search/useInfiniteProductSearchResultsQuery.ts index 0ae40327b..d49a07453 100644 --- a/frontend/src/hooks/queries/search/useInfiniteProductSearchResultsQuery.ts +++ b/frontend/src/hooks/queries/search/useInfiniteProductSearchResultsQuery.ts @@ -1,4 +1,4 @@ -import { useInfiniteQuery } from '@tanstack/react-query'; +import { useSuspendedInfiniteQuery } from '..'; import { searchApi } from '@/apis'; import type { ProductSearchResultResponse } from '@/types/response'; @@ -11,16 +11,17 @@ const fetchProductSearchResults = async (query: string, page: number) => { }; const useInfiniteProductSearchResultsQuery = (query: string) => { - return useInfiniteQuery({ - queryKey: ['search', 'products', 'results', query], - queryFn: ({ pageParam = 0 }) => fetchProductSearchResults(query, pageParam), - getNextPageParam: (prevResponse: ProductSearchResultResponse) => { - const isLast = prevResponse.page.lastPage; - const nextPage = prevResponse.page.requestPage + 1; - return isLast ? undefined : nextPage; - }, - suspense: true, - }); + return useSuspendedInfiniteQuery( + ['search', 'products', 'results', query], + ({ pageParam = 0 }) => fetchProductSearchResults(query, pageParam), + { + getNextPageParam: (prevResponse: ProductSearchResultResponse) => { + const isLast = prevResponse.page.lastPage; + const nextPage = prevResponse.page.requestPage + 1; + return isLast ? undefined : nextPage; + }, + } + ); }; export default useInfiniteProductSearchResultsQuery; From 5ed519e51b00b748d9f2dddf155d562a322bb4e6 Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Wed, 16 Aug 2023 11:32:13 +0900 Subject: [PATCH 15/15] =?UTF-8?q?refactor:=20=EA=BF=80=EC=A1=B0=ED=95=A9?= =?UTF-8?q?=20=EB=AA=A9=EB=A1=9D=20=EC=BF=BC=EB=A6=AC=20useSuspendedInfini?= =?UTF-8?q?teQuery=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/Recipe/RecipeList/RecipeList.tsx | 4 ---- .../src/hooks/queries/recipe/useInfiniteRecipesQuery.ts | 6 ++---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/Recipe/RecipeList/RecipeList.tsx b/frontend/src/components/Recipe/RecipeList/RecipeList.tsx index c89f1ca7e..9e56e32a8 100644 --- a/frontend/src/components/Recipe/RecipeList/RecipeList.tsx +++ b/frontend/src/components/Recipe/RecipeList/RecipeList.tsx @@ -18,10 +18,6 @@ const RecipeList = ({ selectedOption }: RecipeListProps) => { const { fetchNextPage, hasNextPage, data } = useInfiniteRecipesQuery(selectedOption.value); useIntersectionObserver(fetchNextPage, scrollRef, hasNextPage); - if (!data) { - return null; - } - const recipes = data.pages.flatMap((page) => page.recipes); return ( diff --git a/frontend/src/hooks/queries/recipe/useInfiniteRecipesQuery.ts b/frontend/src/hooks/queries/recipe/useInfiniteRecipesQuery.ts index ca2e65697..117212c27 100644 --- a/frontend/src/hooks/queries/recipe/useInfiniteRecipesQuery.ts +++ b/frontend/src/hooks/queries/recipe/useInfiniteRecipesQuery.ts @@ -1,4 +1,4 @@ -import { useInfiniteQuery } from '@tanstack/react-query'; +import { useSuspendedInfiniteQuery } from '..'; import { recipeApi } from '@/apis'; import type { RecipeResponse } from '@/types/response'; @@ -10,9 +10,7 @@ const fetchRecipes = async (pageParam: number, sort: string) => { }; const useInfiniteRecipesQuery = (sort: string) => { - return useInfiniteQuery({ - queryKey: ['recipe', sort], - queryFn: ({ pageParam = 0 }) => fetchRecipes(pageParam, sort), + return useSuspendedInfiniteQuery(['recipe', sort], ({ pageParam = 0 }) => fetchRecipes(pageParam, sort), { getNextPageParam: (prevResponse: RecipeResponse) => { const isLast = prevResponse.page.lastPage; const nextPage = prevResponse.page.requestPage + 1;