From 898eb9d031c06b228bf338f5bb2096eb2f9be4e5 Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Fri, 20 Mar 2026 19:55:12 +0900 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20queryKey=20base=ED=86=B5=EC=9D=BC?= =?UTF-8?q?=20=EB=B0=8F=20=EB=B3=80=EC=88=98=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/features/home/api/company.ts | 2 +- src/features/home/api/recommendation.ts | 4 ++-- src/features/home/consts/queryKeys.ts | 5 ++--- .../home/model/useInfiniteCompaniesPosts.ts | 5 +++-- src/features/home/model/useInfinitePosts.ts | 13 +++++-------- src/features/home/ui/PostCardList.tsx | 2 +- 6 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/features/home/api/company.ts b/src/features/home/api/company.ts index 222dc4e..be9407e 100644 --- a/src/features/home/api/company.ts +++ b/src/features/home/api/company.ts @@ -12,7 +12,7 @@ export const getCompanyList = async () => { export const useGetCompany = () => { return useSuspenseQuery({ queryFn: getCompanyList, - queryKey: [HOME_QUERY_KEY.COMPANY], + queryKey: [HOME_QUERY_KEY.COMPANIES], select: res => res.data, }); }; diff --git a/src/features/home/api/recommendation.ts b/src/features/home/api/recommendation.ts index fa8f03f..7ba6c38 100644 --- a/src/features/home/api/recommendation.ts +++ b/src/features/home/api/recommendation.ts @@ -13,7 +13,7 @@ export const getRecommendPostList = async () => { export const useGetRecommendPostList = (isLogin: boolean) => { return useQuery({ queryKey: [ - HOME_QUERY_KEY.POSTS, + SHARED_QUERY_KEY.POSTS, SHARED_QUERY_KEY.MY, HOME_QUERY_KEY.POSTS_RECOMMEND, ], @@ -32,7 +32,7 @@ export const postRecommendList = async () => { export const usePostRecommendPostList = () => { const queryClient = useQueryClient(); const queryKey = [ - HOME_QUERY_KEY.POSTS, + SHARED_QUERY_KEY.POSTS, SHARED_QUERY_KEY.MY, HOME_QUERY_KEY.POSTS_RECOMMEND, ] as const; diff --git a/src/features/home/consts/queryKeys.ts b/src/features/home/consts/queryKeys.ts index aa3fd53..94c5b5a 100644 --- a/src/features/home/consts/queryKeys.ts +++ b/src/features/home/consts/queryKeys.ts @@ -1,7 +1,6 @@ export const HOME_QUERY_KEY = { - COMPANY: "company", - POSTS: "posts", - POSTS_COMPANIES: "companies", + COMPANIES: "companies", // 게시글이 있는 회사 목록 조회 + POSTS_BY_COMPANY: "by-company", // 회사 기준 게시글 목록 조회 POSTS_RECOMMEND: "recommend", POSTS_SEARCH: "search", } as const; diff --git a/src/features/home/model/useInfiniteCompaniesPosts.ts b/src/features/home/model/useInfiniteCompaniesPosts.ts index 212361b..4869970 100644 --- a/src/features/home/model/useInfiniteCompaniesPosts.ts +++ b/src/features/home/model/useInfiniteCompaniesPosts.ts @@ -1,3 +1,4 @@ +import { SHARED_QUERY_KEY } from "@/shared/consts/queryKeys"; import { getCompaniesPostList } from "../api/post"; import { HOME_QUERY_KEY } from "../consts/queryKeys"; import { useSuspenseInfiniteQuery } from "@tanstack/react-query"; @@ -13,8 +14,8 @@ export const useInfiniteCompaniesPosts = ({ }: UseInfiniteCompaniesPostsParams) => { return useSuspenseInfiniteQuery({ queryKey: [ - HOME_QUERY_KEY.POSTS, - HOME_QUERY_KEY.POSTS_COMPANIES, + SHARED_QUERY_KEY.POSTS, + HOME_QUERY_KEY.POSTS_BY_COMPANY, companies, ] as const, queryFn: ({ pageParam }) => diff --git a/src/features/home/model/useInfinitePosts.ts b/src/features/home/model/useInfinitePosts.ts index df6cde1..a549f2e 100644 --- a/src/features/home/model/useInfinitePosts.ts +++ b/src/features/home/model/useInfinitePosts.ts @@ -1,13 +1,10 @@ import { getPostList } from "../api/post"; -import { HOME_QUERY_KEY } from "../consts/queryKeys"; -import type { - PageParamType, - PostResponseDto, -} from "../api/post.types"; +import type { PageParamType, PostResponseDto } from "../api/post.types"; import { useSuspenseInfiniteQuery, type QueryFunctionContext, } from "@tanstack/react-query"; +import { SHARED_QUERY_KEY } from "@/shared/consts/queryKeys"; interface UseInfinitePostsParams { sortBy: "LATEST" | "POPULAR"; @@ -22,14 +19,14 @@ export const useInfinitePosts = ({ PostResponseDto, Error, PostResponseDto[], - readonly [typeof HOME_QUERY_KEY.POSTS, "LATEST" | "POPULAR"], + readonly [typeof SHARED_QUERY_KEY.POSTS, "LATEST" | "POPULAR"], PageParamType >({ - queryKey: [HOME_QUERY_KEY.POSTS, sortBy] as const, + queryKey: [SHARED_QUERY_KEY.POSTS, sortBy] as const, queryFn: ({ pageParam, }: QueryFunctionContext< - readonly [typeof HOME_QUERY_KEY.POSTS, "LATEST" | "POPULAR"], + readonly [typeof SHARED_QUERY_KEY.POSTS, "LATEST" | "POPULAR"], PageParamType >) => getPostList({ diff --git a/src/features/home/ui/PostCardList.tsx b/src/features/home/ui/PostCardList.tsx index 1e5d1ee..b562a4d 100644 --- a/src/features/home/ui/PostCardList.tsx +++ b/src/features/home/ui/PostCardList.tsx @@ -16,7 +16,7 @@ const PostCardList = ({ selectedTab }: PostCardListProps) => { const { companies } = useCompanyStore(); const infiniteRef = useRef(null); - const companyQuery = useInfiniteCompaniesPosts({ companies }); + const companyQuery = useInfiniteCompaniesPosts({ companies }); //기업별 post List const recentQuery = useInfinitePosts({ sortBy: "LATEST" }); const popularQuery = useInfinitePosts({ sortBy: "POPULAR" }); const { user } = useUserStore(); From 1c21ac8927b157605ced2e864dd983b314952435 Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Fri, 20 Mar 2026 20:46:12 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20cache=20=EC=83=81=EC=88=98=ED=99=94?= =?UTF-8?q?=20=EB=B0=8F=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/features/home/api/company.ts | 3 +++ src/features/home/api/recommendation.ts | 3 +++ src/features/home/api/search.ts | 6 ++++- .../home/model/useInfiniteCompaniesPosts.ts | 7 +++--- src/features/home/model/useInfinitePosts.ts | 6 +++-- .../mypage/model/useInfiniteActivityPosts.ts | 4 +++- src/shared/api/my.ts | 5 +++++ src/shared/consts/cacheTimes.ts | 22 +++++++++++++++++++ 8 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 src/shared/consts/cacheTimes.ts diff --git a/src/features/home/api/company.ts b/src/features/home/api/company.ts index be9407e..488095e 100644 --- a/src/features/home/api/company.ts +++ b/src/features/home/api/company.ts @@ -1,5 +1,6 @@ import { HOME_QUERY_KEY } from "../consts/queryKeys"; import api from "@/shared/api/api"; +import { QUERY_CACHE_TIME } from "@/shared/consts/cacheTimes"; import { API_ENDPOINTS } from "@/shared/consts/endpoints"; import { useSuspenseQuery } from "@tanstack/react-query"; @@ -14,5 +15,7 @@ export const useGetCompany = () => { queryFn: getCompanyList, queryKey: [HOME_QUERY_KEY.COMPANIES], select: res => res.data, + staleTime: QUERY_CACHE_TIME.COMPANIES.staleTime, + gcTime: QUERY_CACHE_TIME.COMPANIES.gcTime, }); }; diff --git a/src/features/home/api/recommendation.ts b/src/features/home/api/recommendation.ts index 7ba6c38..0afacfb 100644 --- a/src/features/home/api/recommendation.ts +++ b/src/features/home/api/recommendation.ts @@ -1,4 +1,5 @@ import api from "@/shared/api/api"; +import { QUERY_CACHE_TIME } from "@/shared/consts/cacheTimes"; import { HOME_QUERY_KEY } from "../consts/queryKeys"; import { SHARED_QUERY_KEY } from "@/shared/consts/queryKeys"; import { API_ENDPOINTS } from "@/shared/consts/endpoints"; @@ -20,6 +21,8 @@ export const useGetRecommendPostList = (isLogin: boolean) => { queryFn: getRecommendPostList, select: res => res.data, enabled: isLogin, + staleTime: QUERY_CACHE_TIME.POSTS.staleTime, + gcTime: QUERY_CACHE_TIME.POSTS.gcTime, }); }; diff --git a/src/features/home/api/search.ts b/src/features/home/api/search.ts index f3a9ee4..d6e5558 100644 --- a/src/features/home/api/search.ts +++ b/src/features/home/api/search.ts @@ -3,7 +3,9 @@ import { useMutation, useSuspenseQuery } from "@tanstack/react-query"; import type { SearchType } from "./search.types"; import { HOME_QUERY_KEY } from "../consts/queryKeys"; import api from "@/shared/api/api"; +import { QUERY_CACHE_TIME } from "@/shared/consts/cacheTimes"; import { API_ENDPOINTS } from "@/shared/consts/endpoints"; +import { SHARED_QUERY_KEY } from "@/shared/consts/queryKeys"; export const getSearchPost = async (query: string) => { const { data } = await api.get(API_ENDPOINTS.search, { params: { query } }); @@ -12,9 +14,11 @@ export const getSearchPost = async (query: string) => { export const useGetSearchPost = (query: string) => { return useSuspenseQuery({ - queryKey: [HOME_QUERY_KEY.POSTS, HOME_QUERY_KEY.POSTS_SEARCH, query], + queryKey: [SHARED_QUERY_KEY.POSTS, HOME_QUERY_KEY.POSTS_SEARCH, query], queryFn: () => getSearchPost(query), select: res => res.data, + staleTime: QUERY_CACHE_TIME.POSTS.staleTime, + gcTime: QUERY_CACHE_TIME.POSTS.gcTime, }); }; diff --git a/src/features/home/model/useInfiniteCompaniesPosts.ts b/src/features/home/model/useInfiniteCompaniesPosts.ts index 4869970..7259694 100644 --- a/src/features/home/model/useInfiniteCompaniesPosts.ts +++ b/src/features/home/model/useInfiniteCompaniesPosts.ts @@ -1,4 +1,5 @@ import { SHARED_QUERY_KEY } from "@/shared/consts/queryKeys"; +import { QUERY_CACHE_TIME } from "@/shared/consts/cacheTimes"; import { getCompaniesPostList } from "../api/post"; import { HOME_QUERY_KEY } from "../consts/queryKeys"; import { useSuspenseInfiniteQuery } from "@tanstack/react-query"; @@ -7,7 +8,7 @@ interface UseInfiniteCompaniesPostsParams { companies: string[]; size?: number; } - +//기업별 게시글 필터링 조회 export const useInfiniteCompaniesPosts = ({ companies, size = 20, @@ -37,7 +38,7 @@ export const useInfiniteCompaniesPosts = ({ }, select: res => res.pages, - staleTime: 1000 * 60 * 5, - gcTime: 1000 * 60 * 10, + staleTime: QUERY_CACHE_TIME.POSTS.staleTime, + gcTime: QUERY_CACHE_TIME.POSTS.gcTime, }); }; diff --git a/src/features/home/model/useInfinitePosts.ts b/src/features/home/model/useInfinitePosts.ts index a549f2e..b685c2a 100644 --- a/src/features/home/model/useInfinitePosts.ts +++ b/src/features/home/model/useInfinitePosts.ts @@ -1,5 +1,6 @@ import { getPostList } from "../api/post"; import type { PageParamType, PostResponseDto } from "../api/post.types"; +import { QUERY_CACHE_TIME } from "@/shared/consts/cacheTimes"; import { useSuspenseInfiniteQuery, type QueryFunctionContext, @@ -11,6 +12,7 @@ interface UseInfinitePostsParams { size?: number; } +//인기순, 최근생성된 게시글 export const useInfinitePosts = ({ sortBy, size = 20, @@ -53,7 +55,7 @@ export const useInfinitePosts = ({ }, select: res => res.pages, - staleTime: 1000 * 60 * 5, - gcTime: 1000 * 60 * 10, + staleTime: QUERY_CACHE_TIME.POSTS.staleTime, + gcTime: QUERY_CACHE_TIME.POSTS.gcTime, }); }; diff --git a/src/features/mypage/model/useInfiniteActivityPosts.ts b/src/features/mypage/model/useInfiniteActivityPosts.ts index 5f4b667..0388580 100644 --- a/src/features/mypage/model/useInfiniteActivityPosts.ts +++ b/src/features/mypage/model/useInfiniteActivityPosts.ts @@ -2,6 +2,7 @@ import { getActivityPostList, type ActivityPostType, } from "@/shared/api/activity"; +import { QUERY_CACHE_TIME } from "@/shared/consts/cacheTimes"; import { MYPAGE_QUERY_KEY } from "../consts/queryKeys"; import { SHARED_QUERY_KEY } from "@/shared/consts/queryKeys"; import { useSuspenseInfiniteQuery } from "@tanstack/react-query"; @@ -31,6 +32,7 @@ export const useInfiniteActivityPosts = (type: ActivityPostType, size = 20) => { }, select: res => res.pages, - gcTime: 1000 * 60 * 5, + staleTime: QUERY_CACHE_TIME.POSTS.staleTime, + gcTime: QUERY_CACHE_TIME.POSTS.gcTime, }); }; diff --git a/src/shared/api/my.ts b/src/shared/api/my.ts index 4614904..f3596d4 100644 --- a/src/shared/api/my.ts +++ b/src/shared/api/my.ts @@ -1,6 +1,7 @@ //사용자와 관련된 정보를 가져옵니다. import { useQuery, useSuspenseQuery } from "@tanstack/react-query"; +import { QUERY_CACHE_TIME } from "../consts/cacheTimes"; import type { InterestResponseDto, InterestTypeDto, @@ -21,6 +22,8 @@ export const useGetMyProfile = (enabled?: boolean) => { queryFn: getMyProfile, select: res => res.data, enabled, + staleTime: QUERY_CACHE_TIME.MY_PROFILE.staleTime, + gcTime: QUERY_CACHE_TIME.MY_PROFILE.gcTime, }); }; @@ -35,5 +38,7 @@ export const useGetMyInterest = () => { queryKey: [SHARED_QUERY_KEY.MY, SHARED_QUERY_KEY.MY_INTEREST], queryFn: getMyInterest, select: res => res.data.interests, + staleTime: QUERY_CACHE_TIME.MY_INTEREST.staleTime, + gcTime: QUERY_CACHE_TIME.MY_INTEREST.gcTime, }); }; diff --git a/src/shared/consts/cacheTimes.ts b/src/shared/consts/cacheTimes.ts new file mode 100644 index 0000000..2a73f9e --- /dev/null +++ b/src/shared/consts/cacheTimes.ts @@ -0,0 +1,22 @@ +export const MINUTE = 1000 * 60; +export const HOUR = MINUTE * 60; + +export const QUERY_CACHE_TIME = { + POSTS: { + //최근 생성된 게시글,인기 게시글,기업별 필터링 게시글,추천 게시글,검색어 기반 게시글 + staleTime: MINUTE * 10, + gcTime: MINUTE * 30, + }, + COMPANIES: { + staleTime: MINUTE * 30, + gcTime: HOUR, + }, + MY_PROFILE: { + staleTime: MINUTE * 5, + gcTime: MINUTE * 30, + }, + MY_INTEREST: { + staleTime: MINUTE * 10, + gcTime: MINUTE * 30, + }, +} as const; From 1ea37f8c9b7817ac34ddd468c0d8cfdeecd40d4b Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Fri, 20 Mar 2026 21:02:29 +0900 Subject: [PATCH 3/8] =?UTF-8?q?remove:=20=EC=A4=91=EB=B3=B5=20type?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/features/home/api/my.types.ts | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 src/features/home/api/my.types.ts diff --git a/src/features/home/api/my.types.ts b/src/features/home/api/my.types.ts deleted file mode 100644 index eeb9953..0000000 --- a/src/features/home/api/my.types.ts +++ /dev/null @@ -1,20 +0,0 @@ -export type MyProfileType = { - nickName: string; - description: string; -}; - -export type InterestTypeDto = { - category: string; - keywords: string[]; -}; - -export type InterestDataDto = { - interests: InterestTypeDto[]; -}; - -export type InterestResponseDto = { - data: InterestDataDto; - code: string; - isSuccess: boolean; - message: string; -}; From 731e34b5d308ac8b4834bc300234336cb225c78d Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Fri, 20 Mar 2026 21:04:21 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20=EA=B4=80=EC=8B=AC=EC=82=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=B6=94?= =?UTF-8?q?=EC=B2=9C=20queryKey=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/features/home/ui/PostCardList.tsx | 1 + src/features/mypage/api/myEdit.ts | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/features/home/ui/PostCardList.tsx b/src/features/home/ui/PostCardList.tsx index b562a4d..9ce0a5e 100644 --- a/src/features/home/ui/PostCardList.tsx +++ b/src/features/home/ui/PostCardList.tsx @@ -48,6 +48,7 @@ const PostCardList = ({ selectedTab }: PostCardListProps) => { (page: PostResponseDto) => page.data.posts, ) ?? []); + console.log(posts); return ( <>
    diff --git a/src/features/mypage/api/myEdit.ts b/src/features/mypage/api/myEdit.ts index 338a27c..8bc8b0d 100644 --- a/src/features/mypage/api/myEdit.ts +++ b/src/features/mypage/api/myEdit.ts @@ -7,6 +7,7 @@ import { useEditTagStore } from "../model/useEditTagStore"; import api from "@/shared/api/api"; import { API_ENDPOINTS } from "@/shared/consts/endpoints"; import { SHARED_QUERY_KEY } from "@/shared/consts/queryKeys"; +import { HOME_QUERY_KEY } from "@/features/home/consts/queryKeys"; import { useMutation, useQueryClient } from "@tanstack/react-query"; // 내 관심사 수정 =>mypage @@ -18,14 +19,21 @@ export const putMyInterst = async (body: InterestDataDto) => { export const usePutMyInterst = () => { const queryClient = useQueryClient(); const queryKey = [SHARED_QUERY_KEY.MY, SHARED_QUERY_KEY.MY_INTEREST] as const; + const recommendQueryKey = [ + SHARED_QUERY_KEY.POSTS, + SHARED_QUERY_KEY.MY, + HOME_QUERY_KEY.POSTS_RECOMMEND, + ] as const; return useMutation({ mutationFn: (body: InterestDataDto) => putMyInterst(body), onMutate: async (payload: InterestDataDto) => { await queryClient.cancelQueries({ queryKey }); + await queryClient.cancelQueries({ queryKey: recommendQueryKey }); const previous = queryClient.getQueryData(queryKey); + const previousRecommend = queryClient.getQueryData(recommendQueryKey); queryClient.setQueryData(queryKey, payload.interests); const { selectedTags } = useEditTagStore.getState(); @@ -33,16 +41,20 @@ export const usePutMyInterst = () => { originalTags: [...selectedTags], }); - return { previous }; + return { previous, previousRecommend }; }, onError: (_err, _payload, context) => { if (context?.previous) { queryClient.setQueryData(queryKey, context.previous); } + if (context?.previousRecommend) { + queryClient.setQueryData(recommendQueryKey, context.previousRecommend); + } }, onSuccess: () => { queryClient.invalidateQueries({ queryKey }); + queryClient.invalidateQueries({ queryKey: recommendQueryKey }); }, }); }; From 1d424ab032363ef08849e69427904b6c3fd15604 Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Fri, 20 Mar 2026 21:13:12 +0900 Subject: [PATCH 5/8] =?UTF-8?q?feat:=20myPage=20tag=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EB=A7=A4=EC=B9=AD=20=EC=98=A4=EB=A5=98=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/mypage/EditInterestPage.tsx | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/pages/mypage/EditInterestPage.tsx b/src/pages/mypage/EditInterestPage.tsx index c51ee5a..3a9b035 100644 --- a/src/pages/mypage/EditInterestPage.tsx +++ b/src/pages/mypage/EditInterestPage.tsx @@ -1,4 +1,4 @@ -import { TAG_MAP } from "@/shared/consts/tags"; +import { TAG_CATEGORY_MAP, TAG_MAP } from "@/shared/consts/tags"; import { tagCodeToLabel } from "@/shared/lib/tagCodeToLabel"; import { INTERESTS_MOCK, @@ -47,6 +47,13 @@ const EditInterestPage = () => { const selectedCategoryData = INTERESTS_MOCK.interests.find( item => item.code === selectedCategory, ); + const selectedCategoryTags = selectedCategoryData + ? TAG_MAP[ + TAG_CATEGORY_MAP[ + selectedCategoryData.code as keyof typeof TAG_CATEGORY_MAP + ] + ] + : []; const isEqual = originalTags.length === selectedTags.length && @@ -160,23 +167,17 @@ const EditInterestPage = () => {

    - {selectedCategoryData?.keywords.map(keyword => { - const categoryLabel = selectedCategoryData.label; - const keywordCode = TAG_MAP[ - categoryLabel as keyof typeof TAG_MAP - ]?.find(item => item.label === keyword)?.code; - - if (!keywordCode) return null; - - const value = `${selectedCategoryData.code}:${keywordCode}`; + {selectedCategoryTags.map(({ code, label }) => { + const value = `${selectedCategoryData?.code}:${code}`; return ( - toggleTag(selectedCategoryData.code, keywordCode) + selectedCategoryData && + toggleTag(selectedCategoryData.code, code) } /> ); From ce0978ae30a2e10ead5958c1c7412c0504a2bc43 Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Sat, 21 Mar 2026 15:10:40 +0900 Subject: [PATCH 6/8] =?UTF-8?q?comment:=20=EC=A3=BC=EC=84=9D=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 --- src/features/mypage/api/myEdit.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/features/mypage/api/myEdit.ts b/src/features/mypage/api/myEdit.ts index 8bc8b0d..b9d7809 100644 --- a/src/features/mypage/api/myEdit.ts +++ b/src/features/mypage/api/myEdit.ts @@ -32,8 +32,8 @@ export const usePutMyInterst = () => { await queryClient.cancelQueries({ queryKey }); await queryClient.cancelQueries({ queryKey: recommendQueryKey }); - const previous = queryClient.getQueryData(queryKey); - const previousRecommend = queryClient.getQueryData(recommendQueryKey); + const previous = queryClient.getQueryData(queryKey); //수정 전 관심사 + const previousRecommend = queryClient.getQueryData(recommendQueryKey); //수정 전 추천글 캐시 queryClient.setQueryData(queryKey, payload.interests); const { selectedTags } = useEditTagStore.getState(); From 124bcc759b36feae8ae72501514100adeee85e35 Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Sat, 21 Mar 2026 15:19:23 +0900 Subject: [PATCH 7/8] =?UTF-8?q?chore:=20Devtools=20=EC=84=A4=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 42 +++++++++++++++++++++++++++++++++++------- package.json | 1 + src/main.tsx | 2 ++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 63ae282..bd7729b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@tailwindcss/vite": "^4.1.18", "@tanstack/react-query": "^5.90.19", + "@tanstack/react-query-devtools": "^5.91.3", "axios": "^1.13.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -1991,9 +1992,19 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.90.19", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.19.tgz", - "integrity": "sha512-GLW5sjPVIvH491VV1ufddnfldyVB+teCnpPIvweEfkpRx7CfUmUGhoh9cdcUKBh/KwVxk22aNEDxeTsvmyB/WA==", + "version": "5.91.2", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.91.2.tgz", + "integrity": "sha512-Uz2pTgPC1mhqrrSGg18RKCWT/pkduAYtxbcyIyKBhw7dTWjXZIzqmpzO2lBkyWr4hlImQgpu1m1pei3UnkFRWw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/query-devtools": { + "version": "5.93.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.93.0.tgz", + "integrity": "sha512-+kpsx1NQnOFTZsw6HAFCW3HkKg0+2cepGtAWXjiiSOJJ1CtQpt72EE2nyZb+AjAbLRPoeRmPJ8MtQd8r8gsPdg==", "license": "MIT", "funding": { "type": "github", @@ -2001,18 +2012,35 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.90.19", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.19.tgz", - "integrity": "sha512-qTZRZ4QyTzQc+M0IzrbKHxSeISUmRB3RPGmao5bT+sI6ayxSRhn0FXEnT5Hg3as8SBFcRosrXXRFB+yAcxVxJQ==", + "version": "5.91.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.91.3.tgz", + "integrity": "sha512-D8jsCexxS5crZxAeiH6VlLHOUzmHOxeW5c11y8rZu0c34u/cy18hUKQXA/gn1Ila3ZIFzP+Pzv76YnliC0EtZQ==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.91.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, + "node_modules/@tanstack/react-query-devtools": { + "version": "5.91.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.91.3.tgz", + "integrity": "sha512-nlahjMtd/J1h7IzOOfqeyDh5LNfG0eULwlltPEonYy0QL+nqrBB+nyzJfULV+moL7sZyxc2sHdNJki+vLA9BSA==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.90.19" + "@tanstack/query-devtools": "5.93.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { + "@tanstack/react-query": "^5.90.20", "react": "^18 || ^19" } }, diff --git a/package.json b/package.json index a42d658..29647ca 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dependencies": { "@tailwindcss/vite": "^4.1.18", "@tanstack/react-query": "^5.90.19", + "@tanstack/react-query-devtools": "^5.91.3", "axios": "^1.13.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", diff --git a/src/main.tsx b/src/main.tsx index e2973e2..59f1f17 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -2,6 +2,7 @@ import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; import "@/app/styles/index.css"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; import { ThemeProvider } from "@/app/providers/ThemProvider.tsx"; import { HelmetProvider } from "react-helmet-async"; import App from "@/app/App"; @@ -14,6 +15,7 @@ createRoot(document.getElementById("root")!).render( + From c59772e58c344ab523d28dbd9aa9c02ade5d26ea Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Sat, 21 Mar 2026 15:24:44 +0900 Subject: [PATCH 8/8] =?UTF-8?q?design:=20=EB=B0=B0=EB=84=88=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/sub_logo.png | Bin 11334 -> 5539 bytes public/sub_logo2.png | Bin 0 -> 11334 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 public/sub_logo2.png diff --git a/public/sub_logo.png b/public/sub_logo.png index 5a9d2b13dd5b55e8d81171468c3a58787b12c31d..4da123a7e7a20798494b74a1b1d0915f1dea5f41 100644 GIT binary patch literal 5539 zcmeHKYf#fi5Z{DHBoL>M#tu6GW);#?cHs5f4g^= z{atX7h3O1a0I*oOB47=Gp%{S7onVYczV%IuLc)ZzB0LGeYzqF7;CRt=G)PKX6XXvi zjkZrw$B^l_+7F=YklE-4BhO+WiQLo1yGTZNr`h){2rRN)lciA13$?ZOccese`sW64*q5Iz zJi6$l{|(=rTMsR)a8S)lwW=RZ-?LQdD}R;uRQBSH5A(V0Otd*1+!=?3{WlUa7OV9_ z?*cswKE^~ChzCYsuB$mvwvY6I#EH%zp^VRSc#lE?vE-?^{A|{XcjST~1E5*gkKJyd zBwA9Gts_+Tt(J%4HTAEb7gL+Oy=cEy`3S4I=|DK5icg%`lx^fDm~E-(IB`3wZu`s5 zPM6LE4QKjXd!WqEu!%Qmn*4G<))fHs#E}MQeFE z=Auf-rUS6%Aubg&b5asR!$1-`fesP}`o^)t&DJ2Ek0LByn6`dncr*zjv0~x*`(N=f zv<^ezY2iA^5kr+~9Yn#9S!Comlr|SZHDyP1kUNIFSkXFYK8DIGbr2InEZq_WVFY

    Bw{##zs7p-i;VvoOTqenhEdCkoB2@ zBH7Rdh!BrKU2hQgvXmECF2&C115c!#3es&zn?W)I#bg0DCpHDGumh_~m8*2BQmkq# zd0Sd0DnXZk-gp3ygEcIXTb)pI^@TAI24(0h_V`SNwiKh8sNH#|qVeI9#UQo{nikhA z^zou)^a=%bj%i27am{nNNIp<(0LAtUlGuqgkxr{klB)Xd^5SAV zeP|mx+KW=h#*UTN*>L?OWX7VRNo3f(YHh0Kk7Kg11CH_8p|W9@7!m{`UW&=9BoV>972$Ag&~OHusjv9AI^3Oal6m z8pq7wHoK;C7j~*FkVohg^4tYViUELrB%~_vA%Y%5s3J_GP}lel{>rd zG~^VbeVwKvCjQ>$ojE1ej;#^KD7{JGj2Tnh8!Z~C8EJEI+>h9cM+z0uq7#w(gklP? z_qrpRuU5Irvtzea6j_jgefgM|)EGj$o?MaqR^;XNsymC?bV3jv&X1qwCZM%g);}I< zMmfXrp8)JTb{*F*j{JOShY_%I5P{h8nD*-t!43uam%Go8&IASv+sba|cU+HO-(Gibo=(4VaB{L17rI52Y|;M zL*NcPI6@;_QH0X|!$H9P5`>-2HzvdFXE73V-it;bCdh$O?wbK zpzM|8de|6(dTtV9JRRA-h}Kh zSq&Tab_&N{FZ3?>09Y`~0wj&mbzcBv2&$9Vz?lE98#OMd z@G(9eKHMkqK!aeT0p`W`=!{2AUn}%3(6iwGkO*TGRbgdGM(bG)&ij>t!2u=yjD7zA D&^PqZ literal 11334 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 oep9>1U+Fq*ga7~l diff --git a/public/sub_logo2.png b/public/sub_logo2.png new file mode 100644 index 0000000000000000000000000000000000000000..5a9d2b13dd5b55e8d81171468c3a58787b12c31d GIT binary patch literal 11334 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 oep9>1U+Fq*ga7~l literal 0 HcmV?d00001