diff --git a/frontend/src/components/Common/CategoryMenu/CategoryMenu.tsx b/frontend/src/components/Common/CategoryMenu/CategoryMenu.tsx index 3eb1f41df..2cb59148f 100644 --- a/frontend/src/components/Common/CategoryMenu/CategoryMenu.tsx +++ b/frontend/src/components/Common/CategoryMenu/CategoryMenu.tsx @@ -2,7 +2,7 @@ import { Button, theme } from '@fun-eat/design-system'; import type { CSSProp } from 'styled-components'; import styled from 'styled-components'; -import { useCategoryContext } from '@/hooks/context'; +import { useCategoryValueContext, useCategoryActionContext } from '@/hooks/context'; import { useCategoryQuery } from '@/hooks/queries/product'; import type { CategoryVariant } from '@/types/common'; @@ -12,7 +12,8 @@ interface CategoryMenuProps { const CategoryMenu = ({ menuVariant }: CategoryMenuProps) => { const { data: categories } = useCategoryQuery(menuVariant); - const { categoryIds, selectCategory } = useCategoryContext(); + const { categoryIds } = useCategoryValueContext(); + const { selectCategory } = useCategoryActionContext(); const currentCategoryId = categoryIds[menuVariant]; return ( diff --git a/frontend/src/components/Product/PBProductList/PBProductList.tsx b/frontend/src/components/Product/PBProductList/PBProductList.tsx index 105415ff7..087fdbed5 100644 --- a/frontend/src/components/Product/PBProductList/PBProductList.tsx +++ b/frontend/src/components/Product/PBProductList/PBProductList.tsx @@ -6,7 +6,7 @@ import PBProductItem from '../PBProductItem/PBProductItem'; import { MoreButton } from '@/components/Common'; import { PATH } from '@/constants/path'; -import { useCategoryContext } from '@/hooks/context'; +import { useCategoryValueContext } from '@/hooks/context'; import { useInfiniteProductsQuery } from '@/hooks/queries/product'; import displaySlice from '@/utils/displaySlice'; @@ -15,7 +15,7 @@ interface PBProductListProps { } const PBProductList = ({ isHomePage }: PBProductListProps) => { - const { categoryIds } = useCategoryContext(); + const { categoryIds } = useCategoryValueContext(); const { data: pbProductListResponse } = useInfiniteProductsQuery(categoryIds.store); const pbProducts = pbProductListResponse.pages.flatMap((page) => page.products); diff --git a/frontend/src/components/Product/ProductList/ProductList.tsx b/frontend/src/components/Product/ProductList/ProductList.tsx index 86d22cd8a..2afa5f995 100644 --- a/frontend/src/components/Product/ProductList/ProductList.tsx +++ b/frontend/src/components/Product/ProductList/ProductList.tsx @@ -7,7 +7,7 @@ import ProductItem from '../ProductItem/ProductItem'; import { PATH } from '@/constants/path'; import { useIntersectionObserver, useScrollRestoration } from '@/hooks/common'; -import { useCategoryContext } from '@/hooks/context'; +import { useCategoryValueContext } from '@/hooks/context'; import { useInfiniteProductsQuery } from '@/hooks/queries/product'; import type { CategoryVariant, SortOption } from '@/types/common'; import displaySlice from '@/utils/displaySlice'; @@ -21,7 +21,7 @@ interface ProductListProps { const ProductList = ({ category, isHomePage, selectedOption }: ProductListProps) => { const scrollRef = useRef(null); - const { categoryIds } = useCategoryContext(); + const { categoryIds } = useCategoryValueContext(); const { fetchNextPage, hasNextPage, data } = useInfiniteProductsQuery( categoryIds[category], diff --git a/frontend/src/contexts/CategoryContext.tsx b/frontend/src/contexts/CategoryContext.tsx index 00065b18c..46e008a97 100644 --- a/frontend/src/contexts/CategoryContext.tsx +++ b/frontend/src/contexts/CategoryContext.tsx @@ -12,19 +12,18 @@ type CategoryIds = { [k in CategoryVariant]: number; }; -interface CategoryState { +interface CategoryValue { categoryIds: CategoryIds; - selectCategory: (menuVariant: string, categoryId: number) => void; currentTabScroll: { [key: number]: number }; +} + +interface CategoryAction { + selectCategory: (menuVariant: string, categoryId: number) => void; saveCurrentTabScroll: (categoryId: number, scrollY: number) => void; } -export const CategoryContext = createContext({ - categoryIds: initialState, - selectCategory: () => {}, - currentTabScroll: {}, - saveCurrentTabScroll: () => {}, -}); +export const CategoryValueContext = createContext(null); +export const CategoryActionContext = createContext(null); const CategoryProvider = ({ children }: PropsWithChildren) => { const [categoryIds, setCategoryIds] = useState(initialState); @@ -38,14 +37,21 @@ const CategoryProvider = ({ children }: PropsWithChildren) => { setCurrentTabScroll((prevState) => ({ ...prevState, [categoryId]: scrollY })); }; - const categoryState: CategoryState = { + const categoryValue = { categoryIds, currentTabScroll, + }; + + const categoryAction = { selectCategory, saveCurrentTabScroll, }; - return {children}; + return ( + + {children} + + ); }; export default CategoryProvider; diff --git a/frontend/src/hooks/common/useScrollRestoration.ts b/frontend/src/hooks/common/useScrollRestoration.ts index 75e1a68e3..c03001048 100644 --- a/frontend/src/hooks/common/useScrollRestoration.ts +++ b/frontend/src/hooks/common/useScrollRestoration.ts @@ -2,10 +2,10 @@ import type { RefObject } from 'react'; import { useEffect } from 'react'; import useTimeout from './useTimeout'; -import { useCategoryContext } from '../context'; +import { useCategoryActionContext } from '../context'; const useScrollRestoration = (currentCategoryId: number, ref: RefObject) => { - const { saveCurrentTabScroll } = useCategoryContext(); + const { saveCurrentTabScroll } = useCategoryActionContext(); const handleScroll = () => { if (!ref.current) return; diff --git a/frontend/src/hooks/context/index.ts b/frontend/src/hooks/context/index.ts index a0a01b373..56470cfbb 100644 --- a/frontend/src/hooks/context/index.ts +++ b/frontend/src/hooks/context/index.ts @@ -1,4 +1,5 @@ -export { default as useCategoryContext } from './useCategoryContext'; +export { default as useCategoryValueContext } from './useCategoryValueContext'; +export { default as useCategoryActionContext } from './useCategoryActionContext'; export { default as useReviewFormActionContext } from './useReviewFormActionContext'; export { default as useReviewFormValueContext } from './useReviewFormValueContext'; export { default as useRecipeFormActionContext } from './useRecipeFormActionContext'; diff --git a/frontend/src/hooks/context/useCategoryActionContext.ts b/frontend/src/hooks/context/useCategoryActionContext.ts new file mode 100644 index 000000000..bc353818d --- /dev/null +++ b/frontend/src/hooks/context/useCategoryActionContext.ts @@ -0,0 +1,14 @@ +import { useContext } from 'react'; + +import { CategoryActionContext } from '@/contexts/CategoryContext'; + +const useCategoryActionContext = () => { + const categoryAction = useContext(CategoryActionContext); + if (categoryAction === null || categoryAction === undefined) { + throw new Error('useCategoryActionContext는 Category Provider 안에서 사용해야 합니다.'); + } + + return categoryAction; +}; + +export default useCategoryActionContext; diff --git a/frontend/src/hooks/context/useCategoryContext.ts b/frontend/src/hooks/context/useCategoryContext.ts deleted file mode 100644 index 9f7a676f8..000000000 --- a/frontend/src/hooks/context/useCategoryContext.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { useContext } from 'react'; - -import { CategoryContext } from '@/contexts/CategoryContext'; - -const useCategoryContext = () => { - const { categoryIds, selectCategory, currentTabScroll, saveCurrentTabScroll } = useContext(CategoryContext); - - return { categoryIds, selectCategory, currentTabScroll, saveCurrentTabScroll }; -}; - -export default useCategoryContext; diff --git a/frontend/src/hooks/context/useCategoryValueContext.ts b/frontend/src/hooks/context/useCategoryValueContext.ts new file mode 100644 index 000000000..2f159e2dd --- /dev/null +++ b/frontend/src/hooks/context/useCategoryValueContext.ts @@ -0,0 +1,14 @@ +import { useContext } from 'react'; + +import { CategoryValueContext } from '@/contexts/CategoryContext'; + +const useCategoryValueContext = () => { + const categoryValue = useContext(CategoryValueContext); + if (categoryValue === null || categoryValue === undefined) { + throw new Error('useCategoryValueContext는 Category Provider 안에서 사용해야 합니다.'); + } + + return categoryValue; +}; + +export default useCategoryValueContext; diff --git a/frontend/src/pages/ProductListPage.tsx b/frontend/src/pages/ProductListPage.tsx index e6bd74764..075a42459 100644 --- a/frontend/src/pages/ProductListPage.tsx +++ b/frontend/src/pages/ProductListPage.tsx @@ -18,7 +18,7 @@ import { ProductList } from '@/components/Product'; import { PRODUCT_SORT_OPTIONS } from '@/constants'; import { PATH } from '@/constants/path'; import { useScrollRestoration, useSortOption } from '@/hooks/common'; -import { useCategoryContext } from '@/hooks/context'; +import { useCategoryValueContext } from '@/hooks/context'; import { isCategoryVariant } from '@/types/common'; const PAGE_TITLE = { food: '공통 상품', store: 'PB 상품' }; @@ -34,7 +34,7 @@ const ProductListPage = () => { const { selectedOption, selectSortOption } = useSortOption(PRODUCT_SORT_OPTIONS[0]); const { reset } = useQueryErrorResetBoundary(); - const { categoryIds, currentTabScroll } = useCategoryContext(); + const { categoryIds, currentTabScroll } = useCategoryValueContext(); const currentCategoryId = categoryIds[category]; const productListRef = useRef(null);