From 8be4ad2a6d452f027577ac17f517d7a3f245647f Mon Sep 17 00:00:00 2001 From: Yeongjun Kim Date: Thu, 3 Apr 2025 19:25:32 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=20=ED=8C=94?= =?UTF-8?q?=EB=A1=9C=EC=9A=B0=20=EC=8B=9C=20=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=EA=B0=80=20=EB=B0=98=EC=98=81=EB=90=98=EB=8F=84=EB=A1=9D=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 --- .../FollowListButton/FollowListButton.tsx | 19 ++---- .../ProfileEditButton/ProfileEditButton.tsx | 25 ++++---- src/components/common/User/User.tsx | 31 +++------- src/hooks/useFollowUser.ts | 60 ++++++------------- src/services/users/useUsers.ts | 46 +++++++++++--- 5 files changed, 80 insertions(+), 101 deletions(-) diff --git a/src/components/FollowListButton/FollowListButton.tsx b/src/components/FollowListButton/FollowListButton.tsx index 5bcf48ee..cb67d9da 100644 --- a/src/components/FollowListButton/FollowListButton.tsx +++ b/src/components/FollowListButton/FollowListButton.tsx @@ -1,7 +1,7 @@ 'use client' import { PROFILE_MSG } from '@/constants' -import { useFollowUser, useModal } from '@/hooks' +import { useModal } from '@/hooks' import { useCurrentUser } from '@/hooks/useCurrentUser' import { fetchGetFollowers, fetchGetFollowing } from '@/services/users/useUsers' import { UserProfileResBody } from '@/types' @@ -13,13 +13,6 @@ const FollowListButton = ({ user }: { user: UserProfileResBody }) => { const myId = currentUser?.memberId const { Modal, isOpen, modalClose, currentModal, handleOpenCurrentModal } = useModal() - const { followingCount, setFollowingCount, followerCount } = useFollowUser({ - memberId: user?.memberId || 0, - isInitFollowing: !!user?.isFollowing, - followingInitCount: user?.followingCount || 0, - followerInitCount: user?.followerCount || 0, - handleOpenCurrentModal, - }) return ( <> @@ -28,7 +21,7 @@ const FollowListButton = ({ user }: { user: UserProfileResBody }) => { onClick={() => { handleOpenCurrentModal('following') }}> - {PROFILE_MSG.FOLLOWING} {followingCount} + {PROFILE_MSG.FOLLOWING} {user?.followingCount} {PROFILE_MSG.LIST_DIVIDER}
{ onClick={() => { handleOpenCurrentModal('follower') }}> - {PROFILE_MSG.FOLLOWER} {followerCount} + {PROFILE_MSG.FOLLOWER} {user?.followerCount}
{currentModal !== 'login' && isOpen && ( { fetchFn={fetchGetFollowing} myId={myId} type="following" - followingCount={followingCount} - setFollowingCount={setFollowingCount} + followingCount={user?.followingCount} /> )} {currentModal === 'follower' && ( @@ -64,8 +56,7 @@ const FollowListButton = ({ user }: { user: UserProfileResBody }) => { fetchFn={fetchGetFollowers} myId={myId} type="follower" - followingCount={followingCount} - setFollowingCount={setFollowingCount} + followingCount={user?.followingCount} /> )} diff --git a/src/components/ProfileEditButton/ProfileEditButton.tsx b/src/components/ProfileEditButton/ProfileEditButton.tsx index e2ff536d..01c9e281 100644 --- a/src/components/ProfileEditButton/ProfileEditButton.tsx +++ b/src/components/ProfileEditButton/ProfileEditButton.tsx @@ -14,44 +14,39 @@ const ProfileEditButton = ({ user }: { user: UserProfileResBody }) => { const { currentUser } = useCurrentUser() const myId = currentUser?.memberId const { handleOpenCurrentModal } = useModal() - const { isFollowing, handleClickFollow } = useFollowUser({ - memberId: user?.memberId || 0, - isInitFollowing: !!user?.isFollowing, - followingInitCount: user?.followingCount || 0, - followerInitCount: user?.followerCount || 0, + const { handleClickFollow } = useFollowUser({ + profileId: user?.memberId || 0, + memberId: currentUser?.memberId || 0, + myId: myId || 0, handleOpenCurrentModal, }) - return myId ? ( + return ( - ) : ( - - - ) } diff --git a/src/components/common/User/User.tsx b/src/components/common/User/User.tsx index 213207f9..d7be0118 100644 --- a/src/components/common/User/User.tsx +++ b/src/components/common/User/User.tsx @@ -1,6 +1,5 @@ 'use client' -import { Dispatch, SetStateAction } from 'react' import { PROFILE_MSG } from '@/constants' import { useFollowUser, useModal } from '@/hooks' import { cls } from '@/utils' @@ -14,12 +13,11 @@ interface UserProps { nickname: string profileImagePath: string aboutMe?: string - isFollowing?: boolean + isFollowing: boolean isAuth?: boolean followingCount?: number myId?: number profileId?: number - setFollowingCount?: Dispatch> } const User = ({ @@ -29,20 +27,16 @@ const User = ({ aboutMe, isFollowing, isAuth, - followingCount, myId, profileId, - setFollowingCount, }: UserProps) => { const { Modal, isOpen, modalClose, currentModal, handleOpenCurrentModal } = useModal() - const { isFollowing: isFollowingValue, handleClickListInFollow } = - useFollowUser({ - profileId: profileId || 0, - memberId: memberId || 0, - isInitFollowing: !!isFollowing, - followerInitCount: followingCount || 0, - }) + const { handleClickListInFollow } = useFollowUser({ + profileId: profileId || 0, + memberId: memberId || 0, + myId: myId || 0, + }) return ( <> @@ -70,23 +64,16 @@ const User = ({ type="button" className={cls( 'button px-2.5 py-1.5 text-sm', - isFollowingValue ? 'button-white' : 'button-emerald', + isFollowing ? 'button-white' : 'button-emerald', )} onClick={() => { if (myId) { - handleClickListInFollow(isFollowingValue) - if (isFollowingValue) { - profileId === myId && - setFollowingCount?.((prev) => prev! - 1) - } else { - profileId === myId && - setFollowingCount?.((prev) => prev! + 1) - } + handleClickListInFollow(isFollowing) } else { handleOpenCurrentModal('login') } }}> - {isFollowingValue ? PROFILE_MSG.FOLLOWING : PROFILE_MSG.FOLLOW} + {isFollowing ? PROFILE_MSG.FOLLOWING : PROFILE_MSG.FOLLOW} )} diff --git a/src/hooks/useFollowUser.ts b/src/hooks/useFollowUser.ts index 94acef6d..039c0983 100644 --- a/src/hooks/useFollowUser.ts +++ b/src/hooks/useFollowUser.ts @@ -1,75 +1,56 @@ -import { useCallback, useEffect, useMemo, useState } from 'react' +import { useCallback, useMemo } from 'react' import { useDeleteFollow, usePostFollow } from '@/services/users/useUsers' -import { useQueryClient } from '@tanstack/react-query' import { debounce } from 'lodash' import { useCurrentUser } from './useCurrentUser' export interface UseFollowUserProps { profileId?: number memberId: number - isInitFollowing: boolean - followingInitCount?: number - followerInitCount: number + myId?: number handleOpenCurrentModal?: (current: string) => void } const useFollowUser = ({ profileId, memberId, - isInitFollowing, - followerInitCount, - followingInitCount, + myId, handleOpenCurrentModal, }: UseFollowUserProps) => { - const queryClient = useQueryClient() const { isLoggedIn } = useCurrentUser() - const [isFollowing, setIsFollowing] = useState(isInitFollowing) - const [followingCount, setFollowingCount] = useState(followingInitCount) - const [followerCount, setFollowerCount] = useState(followerInitCount) - const { mutateAsync: postFollow } = usePostFollow(profileId) - const { mutateAsync: deleteFollow } = useDeleteFollow(profileId) - - useEffect(() => { - setIsFollowing(isInitFollowing) - }, [isInitFollowing]) - - useEffect(() => { - setFollowingCount(followingInitCount) - }, [followingInitCount]) - - useEffect(() => { - setFollowerCount(followerInitCount) - }, [followerInitCount]) + const { mutateAsync: postFollow } = usePostFollow(profileId, myId) + const { mutateAsync: deleteFollow } = useDeleteFollow(profileId, myId) + const targetMemberId = profileId + ? profileId === myId + ? memberId + : profileId + : memberId const debounceUnFollowUser = useMemo( () => debounce(async () => { - if (memberId) { - await deleteFollow({ memberId }) - } + await deleteFollow({ + memberId: targetMemberId, + }) }, 300), - [memberId, deleteFollow], + [targetMemberId, deleteFollow], ) const debounceFollowUser = useMemo( () => debounce(async () => { - if (memberId) { - await postFollow({ memberId }) - } + await postFollow({ + memberId: targetMemberId, + }) }, 300), - [memberId, postFollow], + [targetMemberId, postFollow], ) const handleClickFollow = useCallback( (isFollowing: boolean) => { if (isLoggedIn) { - setIsFollowing((prev) => !prev) if (isFollowing) { - setFollowerCount((prev) => prev - 1) debounceUnFollowUser() } else { - setFollowerCount((prev) => prev + 1) debounceFollowUser() } } else { @@ -86,7 +67,6 @@ const useFollowUser = ({ const handleClickListInFollow = useCallback( (isFollowing: boolean) => { - setIsFollowing((prev) => !prev) if (isFollowing) { debounceUnFollowUser() } else { @@ -97,10 +77,6 @@ const useFollowUser = ({ ) return { - isFollowing, - followingCount, - setFollowingCount, - followerCount, handleClickFollow, handleClickListInFollow, } diff --git a/src/services/users/useUsers.ts b/src/services/users/useUsers.ts index ba73c8f9..79308165 100644 --- a/src/services/users/useUsers.ts +++ b/src/services/users/useUsers.ts @@ -71,6 +71,8 @@ export const usePutUserProfile = (memberId: number) => { }, }) } + +// 멤버 프로필 수정 서버 함수 export const fetchPostUserProfile = async ( userId: number, data: RegisterReqBody, @@ -135,7 +137,7 @@ export const fetchGetFollowers = async ({ } // 팔로우 추가 -export const usePostFollow = (profileId?: number) => { +export const usePostFollow = (profileId?: number, myId?: number) => { const queryClient = useQueryClient() return useMutation({ @@ -145,14 +147,28 @@ export const usePostFollow = (profileId?: number) => { }, onSuccess: () => { queryClient.invalidateQueries({ - queryKey: [QUERY_KEYS.MEMBERS, profileId], + queryKey: [QUERY_KEYS.MEMBERS, profileId || myId], + }) + queryClient.invalidateQueries({ + queryKey: [QUERY_KEYS.FOLLOWING, profileId || myId], }) queryClient.invalidateQueries({ - queryKey: [QUERY_KEYS.FOLLOWING, profileId], + queryKey: [QUERY_KEYS.FOLLOWERS, profileId || myId], }) queryClient.invalidateQueries({ - queryKey: [QUERY_KEYS.FOLLOWERS, profileId], + queryKey: [QUERY_KEYS.MEMBERS], }) + if (profileId !== myId) { + queryClient.invalidateQueries({ + queryKey: [QUERY_KEYS.MEMBERS, myId], + }) + queryClient.invalidateQueries({ + queryKey: [QUERY_KEYS.FOLLOWING, myId], + }) + queryClient.invalidateQueries({ + queryKey: [QUERY_KEYS.FOLLOWERS, myId], + }) + } }, onError: (error: Error) => { console.log(error) @@ -161,7 +177,7 @@ export const usePostFollow = (profileId?: number) => { } // 팔로우 삭제 -export const useDeleteFollow = (profileId?: number) => { +export const useDeleteFollow = (profileId?: number, myId?: number) => { const queryClient = useQueryClient() return useMutation({ @@ -171,14 +187,28 @@ export const useDeleteFollow = (profileId?: number) => { }, onSuccess: () => { queryClient.invalidateQueries({ - queryKey: [QUERY_KEYS.MEMBERS, profileId], + queryKey: [QUERY_KEYS.MEMBERS, profileId || myId], }) queryClient.invalidateQueries({ - queryKey: [QUERY_KEYS.FOLLOWING, profileId], + queryKey: [QUERY_KEYS.FOLLOWING, profileId || myId], }) queryClient.invalidateQueries({ - queryKey: [QUERY_KEYS.FOLLOWERS, profileId], + queryKey: [QUERY_KEYS.FOLLOWERS, profileId || myId], }) + queryClient.invalidateQueries({ + queryKey: [QUERY_KEYS.MEMBERS], + }) + if (profileId !== myId) { + queryClient.invalidateQueries({ + queryKey: [QUERY_KEYS.MEMBERS, myId], + }) + queryClient.invalidateQueries({ + queryKey: [QUERY_KEYS.FOLLOWING, myId], + }) + queryClient.invalidateQueries({ + queryKey: [QUERY_KEYS.FOLLOWERS, myId], + }) + } }, onError: (error: Error) => { console.log(error) From f8096b99802e35c4f0c77c19cde9eef732fb9c90 Mon Sep 17 00:00:00 2001 From: Yeongjun Kim Date: Thu, 3 Apr 2025 19:27:46 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20=EC=BF=BC=EB=A6=AC=20=EB=AC=B4?= =?UTF-8?q?=ED=9A=A8=ED=99=94=20=EC=8B=9C=20Spinner=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EB=A0=8C=EB=8D=94=EB=A7=81=20=EB=90=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(routes)/user/[userId]/page.tsx | 97 ++++++++++--------- .../common/FollowList/FollowList.tsx | 13 +-- .../common/FollowList/hooks/useFollowQuery.ts | 4 +- 3 files changed, 60 insertions(+), 54 deletions(-) diff --git a/src/app/(routes)/user/[userId]/page.tsx b/src/app/(routes)/user/[userId]/page.tsx index e7c0c9f1..df44e786 100644 --- a/src/app/(routes)/user/[userId]/page.tsx +++ b/src/app/(routes)/user/[userId]/page.tsx @@ -1,66 +1,75 @@ +'use client' + import { Avatar, CategoryListItem, FollowListButton, ProfileEditButton, + Spinner, } from '@/components' import { CATEGORIES_RENDER, PROFILE_MSG } from '@/constants' -import { fetchGetUserProfile } from '@/services/users/useUsers' +import { useGetUserProfile } from '@/services/users/useUsers' import { UserLayoutProps } from './layout' -export default async function UserPage({ - params: { userId }, -}: UserLayoutProps) { - const user = await fetchGetUserProfile({ memberId: userId }) +export default function UserPage({ params: { userId } }: UserLayoutProps) { + const { data: user, isFetching: isUserLoading } = useGetUserProfile( + Number(userId), + ) return ( <> -
-
- {user?.profileImagePath && ( -
- + {isUserLoading ? ( + + ) : ( +
+
+ {user?.profileImagePath && ( +
+ +
+ )} +
+
+ {user?.nickname} +
+
+ {user?.newsEmail} +
+
+ +
- )} -
-
- {user?.nickname} -
-
- {user?.newsEmail} +
+ +
+
+ {PROFILE_MSG.FAVORITE_CATEGORY}
-
- +
+
-
- -
-
- {PROFILE_MSG.FAVORITE_CATEGORY} -
- -
-
-
-
- {PROFILE_MSG.DESCRIPTION} +
+ {PROFILE_MSG.DESCRIPTION} +
+
+ {user?.aboutMe} +
-
{user?.aboutMe}
-
+ )} ) } diff --git a/src/components/common/FollowList/FollowList.tsx b/src/components/common/FollowList/FollowList.tsx index 5fcb9cb7..9739f381 100644 --- a/src/components/common/FollowList/FollowList.tsx +++ b/src/components/common/FollowList/FollowList.tsx @@ -1,4 +1,4 @@ -import { Dispatch, Fragment, SetStateAction } from 'react' +import { Fragment, useEffect } from 'react' import { Spinner } from '@/components' import useFollowQuery from '@/components/common/FollowList/hooks/useFollowQuery' import useInfiniteScroll from '@/hooks/useInfiniteScroll' @@ -12,7 +12,6 @@ export interface FollowListProps { myId?: number type?: string followingCount?: number - setFollowingCount?: Dispatch> } export interface FollowUserProps { @@ -29,7 +28,6 @@ const FollowList = ({ myId, type, followingCount, - setFollowingCount, }: FollowListProps) => { const { followList, fetchNextPage, hasNextPage, isFollowLoading } = useFollowQuery({ @@ -38,11 +36,11 @@ const FollowList = ({ type, }) const { target } = useInfiniteScroll({ hasNextPage, fetchNextPage }) - + useEffect(() => { + console.log(isFollowLoading) + }, [isFollowLoading]) return isFollowLoading ? ( - - - + ) : (
    {followList && @@ -60,7 +58,6 @@ const FollowList = ({ followingCount={followingCount} myId={myId} profileId={memberId} - setFollowingCount={setFollowingCount} /> ))} diff --git a/src/components/common/FollowList/hooks/useFollowQuery.ts b/src/components/common/FollowList/hooks/useFollowQuery.ts index 7ca6ada3..3e6942be 100644 --- a/src/components/common/FollowList/hooks/useFollowQuery.ts +++ b/src/components/common/FollowList/hooks/useFollowQuery.ts @@ -5,7 +5,7 @@ import { useInfiniteQuery } from '@tanstack/react-query' const useFollowQuery = ({ memberId, fetchFn, type }: FollowListProps) => { const queryKey = type === 'following' ? QUERY_KEYS.FOLLOWING : QUERY_KEYS.FOLLOWERS - const { data, fetchNextPage, hasNextPage, isLoading } = useInfiniteQuery({ + const { data, fetchNextPage, hasNextPage, isFetching } = useInfiniteQuery({ queryKey: [queryKey, memberId], queryFn: ({ pageParam }) => fetchFn({ @@ -22,7 +22,7 @@ const useFollowQuery = ({ memberId, fetchFn, type }: FollowListProps) => { followList: data, fetchNextPage, hasNextPage, - isFollowLoading: isLoading, + isFollowLoading: isFetching, } } From 5807c08172a1f8e2f1a699611a3d16a1946f45de Mon Sep 17 00:00:00 2001 From: Yeongjun Kim Date: Thu, 3 Apr 2025 21:35:17 +0900 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20=EB=A7=81=ED=81=AC=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94=20=EB=B2=84=ED=8A=BC=20=ED=81=B4=EB=A6=AD=20?= =?UTF-8?q?=EC=8B=9C=20=EC=BF=BC=EB=A6=AC=20=EB=AC=B4=ED=9A=A8=ED=99=94=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PopularLinkList/PopularLinkList.tsx | 4 +-- src/components/common/LinkItem/LinkItem.tsx | 12 ++++----- .../common/LinkItem/hooks/useLikeLink.ts | 25 +++++-------------- src/components/common/LinkList/LinkList.tsx | 4 +-- src/services/link/useLink.ts | 16 ++++++++++-- 5 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/components/PopularLink/PopularLinkList/PopularLinkList.tsx b/src/components/PopularLink/PopularLinkList/PopularLinkList.tsx index 6a15ec64..a22a701e 100644 --- a/src/components/PopularLink/PopularLinkList/PopularLinkList.tsx +++ b/src/components/PopularLink/PopularLinkList/PopularLinkList.tsx @@ -54,8 +54,8 @@ const PopularLinkList = () => { url={link.url} tagName={link.tagName} tagColor={link.tagColor as ChipColors} - isInitLiked={link.isLiked} - likeInitCount={link.likeCount} + isLiked={link.isLiked} + likeCount={link.likeCount} type="card" /> diff --git a/src/components/common/LinkItem/LinkItem.tsx b/src/components/common/LinkItem/LinkItem.tsx index 2d5d0a39..cbe11507 100644 --- a/src/components/common/LinkItem/LinkItem.tsx +++ b/src/components/common/LinkItem/LinkItem.tsx @@ -44,8 +44,8 @@ export interface LinkItemProps { tagName: string tagColor: ChipColors readUsers?: linkViewHistories[] - isInitLiked?: boolean - likeInitCount: number + isLiked: boolean + likeCount: number read?: boolean summary?: boolean edit?: boolean @@ -62,8 +62,8 @@ const LinkItem = ({ tagName, tagColor, readUsers, - isInitLiked, - likeInitCount, + isLiked, + likeCount, read = false, summary = false, edit = false, @@ -110,11 +110,9 @@ const LinkItem = ({ linkId, }) const { handleSaveReadInfo } = useReadSaveLink({ spaceId, linkId }) - const { isLiked, likeCount, handleClickLike } = useLikeLink({ + const { handleClickLike } = useLikeLink({ spaceId, linkId, - isLikedValue: isInitLiked, - likeCountValue: likeInitCount, }) return ( <> diff --git a/src/components/common/LinkItem/hooks/useLikeLink.ts b/src/components/common/LinkItem/hooks/useLikeLink.ts index 7bb76faa..fe09f582 100644 --- a/src/components/common/LinkItem/hooks/useLikeLink.ts +++ b/src/components/common/LinkItem/hooks/useLikeLink.ts @@ -1,25 +1,15 @@ -import { useCallback, useMemo, useState } from 'react' +import { useCallback, useMemo } from 'react' import { useDeleteLikeLink, usePostLikeLink } from '@/services/link/useLink' import { debounce } from 'lodash' -import useToggle from '../../Toggle/hooks/useToggle' export interface UseLikeLinkProps { spaceId?: number linkId: number - isLikedValue?: boolean - likeCountValue: number } -const useLikeLink = ({ - linkId, - isLikedValue, - likeCountValue, -}: UseLikeLinkProps) => { - const [isLiked, likeToggle] = useToggle(isLikedValue) - const [likeCount, setLikeCount] = useState(likeCountValue) - - const { mutate: deleteLikeLink } = useDeleteLikeLink() - const { mutate: postLikeLink } = usePostLikeLink() +const useLikeLink = ({ spaceId, linkId }: UseLikeLinkProps) => { + const { mutate: deleteLikeLink } = useDeleteLikeLink({ spaceId }) + const { mutate: postLikeLink } = usePostLikeLink({ spaceId }) const debounceUnLikeLink = useMemo( () => @@ -39,19 +29,16 @@ const useLikeLink = ({ const handleClickLike = useCallback( (isLike: boolean) => { - likeToggle() if (isLike) { - setLikeCount((prev) => prev - 1) debounceUnLikeLink() } else { - setLikeCount((prev) => prev + 1) debounceLikeLink() } }, - [likeToggle, debounceUnLikeLink, debounceLikeLink], + [debounceUnLikeLink, debounceLikeLink], ) - return { isLiked, likeCount, handleClickLike } + return { handleClickLike } } export default useLikeLink diff --git a/src/components/common/LinkList/LinkList.tsx b/src/components/common/LinkList/LinkList.tsx index 5a913d29..7a3de0c2 100644 --- a/src/components/common/LinkList/LinkList.tsx +++ b/src/components/common/LinkList/LinkList.tsx @@ -151,8 +151,8 @@ const LinkList = ({ tagName={link.tagName} tagColor={link.tagColor} readUsers={link.linkViewHistories} - isInitLiked={link.isLiked} - likeInitCount={link.likeCount} + isLiked={link.isLiked} + likeCount={link.likeCount} read={read} summary={summary} edit={edit} diff --git a/src/services/link/useLink.ts b/src/services/link/useLink.ts index f26bf40a..521e9d01 100644 --- a/src/services/link/useLink.ts +++ b/src/services/link/useLink.ts @@ -124,7 +124,9 @@ export const fetchGetPopularLinks = async () => { } // 링크 좋아요 -export const usePostLikeLink = () => { +export const usePostLikeLink = ({ spaceId }: { spaceId?: number }) => { + const queryClient = useQueryClient() + return useMutation({ mutationFn: async (query: ILikeLink['query']) => { const response = await apiClient.post( @@ -133,6 +135,10 @@ export const usePostLikeLink = () => { ) return response }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.LINKS, spaceId] }) + queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.POPULAR_LINKS] }) + }, onError: (error: Error) => { console.log(error) }, @@ -140,12 +146,18 @@ export const usePostLikeLink = () => { } // 링크 좋아요 취소 -export const useDeleteLikeLink = () => { +export const useDeleteLikeLink = ({ spaceId }: { spaceId?: number }) => { + const queryClient = useQueryClient() + return useMutation({ mutationFn: async (query: ILikeLink['query']) => { const response = await apiClient.delete(`/api/links/${query.linkId}/like`) return response }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.LINKS, spaceId] }) + queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.POPULAR_LINKS] }) + }, onError: (error: Error) => { console.log(error) }, From 95f816efdc04b812b310ec6dc45f4929e94d38f4 Mon Sep 17 00:00:00 2001 From: Yeongjun Kim Date: Thu, 3 Apr 2025 21:51:36 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20=EB=A7=81=ED=81=AC=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94=20=EB=B2=84=ED=8A=BC=EC=97=90=20=EB=94=94?= =?UTF-8?q?=EB=B0=94=EC=9A=B4=EC=8A=A4=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/LinkItem/hooks/useLikeLink.ts | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/components/common/LinkItem/hooks/useLikeLink.ts b/src/components/common/LinkItem/hooks/useLikeLink.ts index fe09f582..b4cbe65e 100644 --- a/src/components/common/LinkItem/hooks/useLikeLink.ts +++ b/src/components/common/LinkItem/hooks/useLikeLink.ts @@ -1,6 +1,5 @@ -import { useCallback, useMemo } from 'react' +import { useCallback } from 'react' import { useDeleteLikeLink, usePostLikeLink } from '@/services/link/useLink' -import { debounce } from 'lodash' export interface UseLikeLinkProps { spaceId?: number @@ -11,31 +10,23 @@ const useLikeLink = ({ spaceId, linkId }: UseLikeLinkProps) => { const { mutate: deleteLikeLink } = useDeleteLikeLink({ spaceId }) const { mutate: postLikeLink } = usePostLikeLink({ spaceId }) - const debounceUnLikeLink = useMemo( - () => - debounce(async () => { - await deleteLikeLink({ linkId }) - }, 300), - [deleteLikeLink, linkId], - ) + const handleRemoveLike = useCallback(() => { + deleteLikeLink({ linkId }) + }, [deleteLikeLink, linkId]) - const debounceLikeLink = useMemo( - () => - debounce(async () => { - await postLikeLink({ linkId }) - }, 300), - [postLikeLink, linkId], - ) + const handleAddLike = useCallback(() => { + postLikeLink({ linkId }) + }, [postLikeLink, linkId]) const handleClickLike = useCallback( (isLike: boolean) => { if (isLike) { - debounceUnLikeLink() + handleRemoveLike() } else { - debounceLikeLink() + handleAddLike() } }, - [debounceUnLikeLink, debounceLikeLink], + [handleRemoveLike, handleAddLike], ) return { handleClickLike } From 192ee59785fe282999f4ff6c3a9d1c1afe373e8f Mon Sep 17 00:00:00 2001 From: Yeongjun Kim Date: Fri, 4 Apr 2025 01:39:38 +0900 Subject: [PATCH 5/7] =?UTF-8?q?feat:=20=ED=8C=94=EB=A1=9C=EC=9A=B0=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EB=94=94=EB=B0=94=EC=9A=B4=EC=8A=A4=20?= =?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/hooks/useFollowUser.ts | 40 ++++++++++++++------------------------ 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/src/hooks/useFollowUser.ts b/src/hooks/useFollowUser.ts index 039c0983..6da30ab3 100644 --- a/src/hooks/useFollowUser.ts +++ b/src/hooks/useFollowUser.ts @@ -1,6 +1,5 @@ -import { useCallback, useMemo } from 'react' +import { useCallback } from 'react' import { useDeleteFollow, usePostFollow } from '@/services/users/useUsers' -import { debounce } from 'lodash' import { useCurrentUser } from './useCurrentUser' export interface UseFollowUserProps { @@ -25,23 +24,19 @@ const useFollowUser = ({ : profileId : memberId - const debounceUnFollowUser = useMemo( + const handleRemoveFollow = useCallback( () => - debounce(async () => { - await deleteFollow({ - memberId: targetMemberId, - }) - }, 300), + deleteFollow({ + memberId: targetMemberId, + }), [targetMemberId, deleteFollow], ) - const debounceFollowUser = useMemo( + const handleAddFollow = useCallback( () => - debounce(async () => { - await postFollow({ - memberId: targetMemberId, - }) - }, 300), + postFollow({ + memberId: targetMemberId, + }), [targetMemberId, postFollow], ) @@ -49,31 +44,26 @@ const useFollowUser = ({ (isFollowing: boolean) => { if (isLoggedIn) { if (isFollowing) { - debounceUnFollowUser() + handleRemoveFollow() } else { - debounceFollowUser() + handleAddFollow() } } else { handleOpenCurrentModal?.('login') } }, - [ - debounceUnFollowUser, - debounceFollowUser, - isLoggedIn, - handleOpenCurrentModal, - ], + [handleRemoveFollow, handleAddFollow, isLoggedIn, handleOpenCurrentModal], ) const handleClickListInFollow = useCallback( (isFollowing: boolean) => { if (isFollowing) { - debounceUnFollowUser() + handleRemoveFollow() } else { - debounceFollowUser() + handleAddFollow() } }, - [debounceUnFollowUser, debounceFollowUser], + [handleRemoveFollow, handleAddFollow], ) return { From a50379d29d3eb763d5be930b688bf66f7d2af381 Mon Sep 17 00:00:00 2001 From: Yeongjun Kim Date: Fri, 4 Apr 2025 01:45:22 +0900 Subject: [PATCH 6/7] =?UTF-8?q?feat:=20id=EA=B0=80=20=EC=A1=B4=EC=9E=AC?= =?UTF-8?q?=ED=95=A0=20=EB=95=8C=20=EB=A0=8C=EB=8D=94=EB=A7=81=20=EB=90=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProfileEditButton/ProfileEditButton.tsx | 57 ++++++++++--------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/components/ProfileEditButton/ProfileEditButton.tsx b/src/components/ProfileEditButton/ProfileEditButton.tsx index 01c9e281..9f54dd5a 100644 --- a/src/components/ProfileEditButton/ProfileEditButton.tsx +++ b/src/components/ProfileEditButton/ProfileEditButton.tsx @@ -6,8 +6,6 @@ import { UserProfileResBody } from '@/types' import { cls, getProfileButtonColor, getProfileButtonText } from '@/utils' import { useRouter } from 'next/navigation' import Button from '../common/Button/Button' -import DeferredComponent from '../common/DeferedComponent/DeferedComponent' -import Spinner from '../common/Spinner/Spinner' const ProfileEditButton = ({ user }: { user: UserProfileResBody }) => { const router = useRouter() @@ -21,32 +19,37 @@ const ProfileEditButton = ({ user }: { user: UserProfileResBody }) => { handleOpenCurrentModal, }) + const buttonColor = getProfileButtonColor({ + isFollowing: user?.isFollowing, + memberId: user?.memberId, + myId, + }) + + const buttonText = getProfileButtonText({ + isFollowing: user?.isFollowing, + memberId: user?.memberId, + myId, + }) + return ( - + <> + {user?.memberId && myId && ( + + )} + ) } From 034f867b48c69362d61d88e13ec3a370fc583e82 Mon Sep 17 00:00:00 2001 From: Yeongjun Kim Date: Fri, 4 Apr 2025 01:46:58 +0900 Subject: [PATCH 7/7] =?UTF-8?q?feat:=20=EB=A1=9C=EB=94=A9=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=EC=9D=BC=20=EB=95=8C=20=EC=9A=94=EC=86=8C=20=EC=9C=84?= =?UTF-8?q?=EC=97=90=20Spinner=EA=B0=80=20=EB=A0=8C=EB=8D=94=EB=A7=81=20?= =?UTF-8?q?=EB=90=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(routes)/user/[userId]/page.tsx | 85 +++++++++---------- .../common/FollowList/FollowList.tsx | 57 ++++++------- 2 files changed, 68 insertions(+), 74 deletions(-) diff --git a/src/app/(routes)/user/[userId]/page.tsx b/src/app/(routes)/user/[userId]/page.tsx index df44e786..c5416c4e 100644 --- a/src/app/(routes)/user/[userId]/page.tsx +++ b/src/app/(routes)/user/[userId]/page.tsx @@ -18,58 +18,53 @@ export default function UserPage({ params: { userId } }: UserLayoutProps) { return ( <> - {isUserLoading ? ( - - ) : ( -
    -
    - {user?.profileImagePath && ( -
    - -
    - )} -
    -
    - {user?.nickname} -
    -
    - {user?.newsEmail} -
    -
    - -
    + {isUserLoading && } +
    +
    + {user?.profileImagePath && ( +
    +
    -
    - -
    -
    - {PROFILE_MSG.FAVORITE_CATEGORY} + )} +
    +
    + {user?.nickname}
    -
    - +
    + {user?.newsEmail}
    +
    + +
    +
    +
    + +
    +
    + {PROFILE_MSG.FAVORITE_CATEGORY}
    -
    - {PROFILE_MSG.DESCRIPTION} -
    -
    - {user?.aboutMe} -
    + +
    +
    +
    +
    + {PROFILE_MSG.DESCRIPTION}
    +
    {user?.aboutMe}
    - )} +
    ) } diff --git a/src/components/common/FollowList/FollowList.tsx b/src/components/common/FollowList/FollowList.tsx index 9739f381..b8108500 100644 --- a/src/components/common/FollowList/FollowList.tsx +++ b/src/components/common/FollowList/FollowList.tsx @@ -36,35 +36,34 @@ const FollowList = ({ type, }) const { target } = useInfiniteScroll({ hasNextPage, fetchNextPage }) - useEffect(() => { - console.log(isFollowLoading) - }, [isFollowLoading]) - return isFollowLoading ? ( - - ) : ( -
      - {followList && - followList.pages.map((group, i) => ( - - {group.responses?.map((user: FollowUserProps) => ( -
    • - -
    • - ))} -
      - ))} -
      -
    + + return ( + <> + {isFollowLoading && } +
      + {followList && + followList.pages.map((group, i) => ( + + {group.responses?.map((user: FollowUserProps) => ( +
    • + +
    • + ))} +
      + ))} +
      +
    + ) }