From 17ba32c5fdb7b806d32dcbcd08237c8e7408fcdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=A0=95=EB=AF=BC?= Date: Sat, 12 Oct 2024 16:07:24 +0900 Subject: [PATCH 1/5] =?UTF-8?q?refactor:=20comments=20=EC=BF=BC=EB=A6=AC?= =?UTF-8?q?=EB=A5=BC=20=EC=BF=BC=EB=A6=AC=20=EC=98=B5=EC=85=98=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=EC=9C=BC=EB=A1=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/features/comments/components/CommentList.tsx | 5 +++-- frontend/src/features/comments/queries/index.ts | 9 +++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/frontend/src/features/comments/components/CommentList.tsx b/frontend/src/features/comments/components/CommentList.tsx index 741ac7b8..a6170675 100644 --- a/frontend/src/features/comments/components/CommentList.tsx +++ b/frontend/src/features/comments/components/CommentList.tsx @@ -1,10 +1,11 @@ +import { useQuery } from '@tanstack/react-query'; import { styled } from 'styled-components'; import cancelIcon from '@/assets/icon/cancel.svg'; import BottomSheet from '@/shared/components/BottomSheet/BottomSheet'; import Spacing from '@/shared/components/Spacing'; import SRHeading from '@/shared/components/SRHeading'; import { useOverlay } from '@/shared/hooks/useOverlay'; -import { useCommentsQuery } from '../queries'; +import { commentsQueryOptions } from '../queries'; import Comment from './Comment'; import CommentForm from './CommentForm'; import type { Comment as CommentType } from '../types/comment.type'; @@ -41,7 +42,7 @@ const CommentList = ({ songId, partId }: CommentListProps) => { )); - const { comments } = useCommentsQuery(songId, partId); + const { data: comments } = useQuery(commentsQueryOptions(songId, partId)); if (!comments) { return null; diff --git a/frontend/src/features/comments/queries/index.ts b/frontend/src/features/comments/queries/index.ts index 1e52cb10..8bbf8063 100644 --- a/frontend/src/features/comments/queries/index.ts +++ b/frontend/src/features/comments/queries/index.ts @@ -1,15 +1,12 @@ -import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { queryOptions, useMutation, useQueryClient } from '@tanstack/react-query'; import { getComments, postComment } from '../remotes/comments'; -export const useCommentsQuery = (songId: number, partId: number) => { - const { data: comments, ...queries } = useQuery({ +export const commentsQueryOptions = (songId: number, partId: number) => + queryOptions({ queryKey: ['comments', songId, partId], queryFn: () => getComments(songId, partId), }); - return { comments, queries }; -}; - export const usePostCommentMutation = () => { const client = useQueryClient(); From 4f09b238479dd1f409de076d176a36a7c02f30d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=A0=95=EB=AF=BC?= Date: Sat, 12 Oct 2024 16:10:06 +0900 Subject: [PATCH 2/5] =?UTF-8?q?refactor:=20songDetailEntries=20=EC=BF=BC?= =?UTF-8?q?=EB=A6=AC=EB=A5=BC=20=EC=BF=BC=EB=A6=AC=20=EC=98=B5=EC=85=98=20?= =?UTF-8?q?=EA=B8=B0=EB=B0=98=EC=9C=BC=EB=A1=9C=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/features/songs/hooks/useSongDetailEntries.ts | 10 +++++----- frontend/src/features/songs/queries/index.ts | 11 ++++------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/frontend/src/features/songs/hooks/useSongDetailEntries.ts b/frontend/src/features/songs/hooks/useSongDetailEntries.ts index ca0cba30..d9e18771 100644 --- a/frontend/src/features/songs/hooks/useSongDetailEntries.ts +++ b/frontend/src/features/songs/hooks/useSongDetailEntries.ts @@ -1,15 +1,15 @@ +import { useQuery } from '@tanstack/react-query'; import { useCallback } from 'react'; import useValidParams from '@/shared/hooks/useValidParams'; -import { useSongDetailEntriesQuery } from '../queries'; +import { songDetailEntriesQueryOptions } from '../queries'; import type { Genre } from '../types/Song.type'; const useSongDetailEntries = () => { const { id: songIdParams, genre: genreParams } = useValidParams(); - const { - songDetailEntries, - queries: { isLoading: isLoadingSongDetailEntries }, - } = useSongDetailEntriesQuery(Number(songIdParams), genreParams as Genre); + const { data: songDetailEntries, isLoading: isLoadingSongDetailEntries } = useQuery( + songDetailEntriesQueryOptions(Number(songIdParams), genreParams as Genre) + ); const scrollIntoCurrentSong: React.RefCallback = useCallback((dom) => { if (dom !== null) dom.scrollIntoView({ behavior: 'instant', block: 'start' }); diff --git a/frontend/src/features/songs/queries/index.ts b/frontend/src/features/songs/queries/index.ts index 12454dc1..cd954ee4 100644 --- a/frontend/src/features/songs/queries/index.ts +++ b/frontend/src/features/songs/queries/index.ts @@ -1,4 +1,4 @@ -import { useInfiniteQuery, useQuery } from '@tanstack/react-query'; +import { queryOptions, useInfiniteQuery } from '@tanstack/react-query'; import { getExtraNextSongDetails, getExtraPrevSongDetails, @@ -6,16 +6,13 @@ import { } from '../remotes/songs'; import type { Genre } from '../types/Song.type'; -export const useSongDetailEntriesQuery = (songId: number, genre: Genre) => { - const { data: songDetailEntries, ...queries } = useQuery({ - queryKey: ['songDetailEntries'], +export const songDetailEntriesQueryOptions = (songId: number, genre: Genre) => + queryOptions({ + queryKey: ['songDetailEntries', songId, genre], queryFn: () => getSongDetailEntries(songId, genre), staleTime: Infinity, }); - return { songDetailEntries, queries }; -}; - export const useExtraPrevSongDetailsInfiniteQuery = (songId: number, genre: Genre) => { const { data: extraPrevSongDetails, From 7d355b7c0a0f8ea57ae1478791ffcfa997d54918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=A0=95=EB=AF=BC?= Date: Sat, 12 Oct 2024 16:16:37 +0900 Subject: [PATCH 3/5] =?UTF-8?q?refactor:=20extraPrevSongDetails,=20extraNe?= =?UTF-8?q?xtSongDetails=20=EC=9D=B8=ED=94=BC=EB=8B=88=ED=8A=B8=20?= =?UTF-8?q?=EC=BF=BC=EB=A6=AC=EB=A5=BC=20=EC=BF=BC=EB=A6=AC=20=EC=98=B5?= =?UTF-8?q?=EC=85=98=20=EA=B8=B0=EB=B0=98=EC=9C=BC=EB=A1=9C=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../songs/hooks/useExtraSongDetail.ts | 27 ++++++++++++------- frontend/src/features/songs/queries/index.ts | 24 ++++------------- 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/frontend/src/features/songs/hooks/useExtraSongDetail.ts b/frontend/src/features/songs/hooks/useExtraSongDetail.ts index cbabaf23..d1556732 100644 --- a/frontend/src/features/songs/hooks/useExtraSongDetail.ts +++ b/frontend/src/features/songs/hooks/useExtraSongDetail.ts @@ -1,9 +1,10 @@ +import { useInfiniteQuery } from '@tanstack/react-query'; import { useCallback, useRef } from 'react'; import useValidParams from '@/shared/hooks/useValidParams'; import createObserver from '@/shared/utils/createObserver'; import { - useExtraNextSongDetailsInfiniteQuery, - useExtraPrevSongDetailsInfiniteQuery, + extraPrevSongDetailsInfiniteQueryOptions, + extraNextSongDetailsInfiniteQueryOptions, } from '../queries'; import type { Genre } from '../types/Song.type'; @@ -11,16 +12,22 @@ const useExtraSongDetail = () => { const { id: songIdParams, genre: genreParams } = useValidParams(); const { - extraPrevSongDetails, - fetchExtraPrevSongDetails, - infiniteQueries: { isLoading: isLoadingPrevSongDetails, hasPreviousPage }, - } = useExtraPrevSongDetailsInfiniteQuery(Number(songIdParams), genreParams as Genre); + data: extraPrevSongDetails, + fetchPreviousPage: fetchExtraPrevSongDetails, + isLoading: isLoadingPrevSongDetails, + hasPreviousPage, + } = useInfiniteQuery( + extraPrevSongDetailsInfiniteQueryOptions(Number(songIdParams), genreParams as Genre) + ); const { - extraNextSongDetails, - fetchExtraNextSongDetails, - infiniteQueries: { isLoading: isLoadingNextSongDetails, hasNextPage }, - } = useExtraNextSongDetailsInfiniteQuery(Number(songIdParams), genreParams as Genre); + data: extraNextSongDetails, + fetchPreviousPage: fetchExtraNextSongDetails, + isLoading: isLoadingNextSongDetails, + hasNextPage, + } = useInfiniteQuery( + extraNextSongDetailsInfiniteQueryOptions(Number(songIdParams), genreParams as Genre) + ); const prevObserverRef = useRef(null); const nextObserverRef = useRef(null); diff --git a/frontend/src/features/songs/queries/index.ts b/frontend/src/features/songs/queries/index.ts index cd954ee4..87ef32d8 100644 --- a/frontend/src/features/songs/queries/index.ts +++ b/frontend/src/features/songs/queries/index.ts @@ -1,4 +1,4 @@ -import { queryOptions, useInfiniteQuery } from '@tanstack/react-query'; +import { infiniteQueryOptions, queryOptions } from '@tanstack/react-query'; import { getExtraNextSongDetails, getExtraPrevSongDetails, @@ -13,12 +13,8 @@ export const songDetailEntriesQueryOptions = (songId: number, genre: Genre) => staleTime: Infinity, }); -export const useExtraPrevSongDetailsInfiniteQuery = (songId: number, genre: Genre) => { - const { - data: extraPrevSongDetails, - fetchPreviousPage: fetchExtraPrevSongDetails, - ...infiniteQueries - } = useInfiniteQuery({ +export const extraPrevSongDetailsInfiniteQueryOptions = (songId: number, genre: Genre) => + infiniteQueryOptions({ queryKey: ['extraPrevSongDetails'], queryFn: ({ pageParam }) => getExtraPrevSongDetails(pageParam, genre), getPreviousPageParam: (firstPage) => firstPage[0]?.id ?? null, @@ -27,21 +23,11 @@ export const useExtraPrevSongDetailsInfiniteQuery = (songId: number, genre: Genr staleTime: Infinity, }); - return { extraPrevSongDetails, fetchExtraPrevSongDetails, infiniteQueries }; -}; - -export const useExtraNextSongDetailsInfiniteQuery = (songId: number, genre: Genre) => { - const { - data: extraNextSongDetails, - fetchNextPage: fetchExtraNextSongDetails, - ...infiniteQueries - } = useInfiniteQuery({ +export const extraNextSongDetailsInfiniteQueryOptions = (songId: number, genre: Genre) => + infiniteQueryOptions({ queryKey: ['extraNextSongDetails'], queryFn: ({ pageParam }) => getExtraNextSongDetails(pageParam, genre), getNextPageParam: (lastPage) => lastPage.at(-1)?.id ?? null, initialPageParam: songId, staleTime: Infinity, }); - - return { extraNextSongDetails, fetchExtraNextSongDetails, infiniteQueries }; -}; From 2130edf44e2fd39f4a6f8d07521503a82fe33d0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=A0=95=EB=AF=BC?= Date: Sat, 12 Oct 2024 16:25:44 +0900 Subject: [PATCH 4/5] =?UTF-8?q?refactor:=20mutate=20=EC=98=B5=EC=85=98?= =?UTF-8?q?=EC=9D=B4=20=EB=93=9C=EB=9F=AC=EB=82=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=A7=81=EC=A0=91=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comments/components/CommentForm.tsx | 14 +++++++++----- frontend/src/features/comments/queries/index.ts | 17 ++--------------- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/frontend/src/features/comments/components/CommentForm.tsx b/frontend/src/features/comments/components/CommentForm.tsx index 3fda9f16..8f1dbca7 100644 --- a/frontend/src/features/comments/components/CommentForm.tsx +++ b/frontend/src/features/comments/components/CommentForm.tsx @@ -1,3 +1,4 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useState } from 'react'; import { css, styled } from 'styled-components'; import defaultAvatar from '@/assets/icon/avatar-default.svg'; @@ -7,7 +8,7 @@ import LoginModal from '@/features/auth/components/LoginModal'; import Avatar from '@/shared/components/Avatar'; import useToastContext from '@/shared/components/Toast/hooks/useToastContext'; import { useOverlay } from '@/shared/hooks/useOverlay'; -import { usePostCommentMutation } from '../queries'; +import { postComment } from '../remotes/comments'; interface CommentFormProps { songId: number; @@ -18,6 +19,7 @@ const CommentForm = ({ songId, partId }: CommentFormProps) => { const [newComment, setNewComment] = useState(''); const [isLoginModalOpen, setIsLoginModalOpen] = useState(false); const overlay = useOverlay(); + const queryClient = useQueryClient(); const openLoginModal = () => { setIsLoginModalOpen(true); @@ -38,10 +40,12 @@ const CommentForm = ({ songId, partId }: CommentFormProps) => { const isLoggedIn = !!user; - const { - postNewComment, - mutations: { isPending: isPendingPostComment }, - } = usePostCommentMutation(); + const { mutate: postNewComment, isPending: isPendingPostComment } = useMutation({ + mutationFn: postComment, + onSuccess: (_, { songId, partId }) => { + queryClient.invalidateQueries({ queryKey: ['comments', songId, partId] }); + }, + }); const { showToast } = useToastContext(); diff --git a/frontend/src/features/comments/queries/index.ts b/frontend/src/features/comments/queries/index.ts index 8bbf8063..a8125850 100644 --- a/frontend/src/features/comments/queries/index.ts +++ b/frontend/src/features/comments/queries/index.ts @@ -1,21 +1,8 @@ -import { queryOptions, useMutation, useQueryClient } from '@tanstack/react-query'; -import { getComments, postComment } from '../remotes/comments'; +import { queryOptions } from '@tanstack/react-query'; +import { getComments } from '../remotes/comments'; export const commentsQueryOptions = (songId: number, partId: number) => queryOptions({ queryKey: ['comments', songId, partId], queryFn: () => getComments(songId, partId), }); - -export const usePostCommentMutation = () => { - const client = useQueryClient(); - - const { mutate: postNewComment, ...mutations } = useMutation({ - mutationFn: postComment, - onSuccess: (_, { songId, partId }) => { - client.invalidateQueries({ queryKey: ['comments', songId, partId] }); - }, - }); - - return { postNewComment, mutations }; -}; From 80669dc8cbee116c15cd3ef6af2e2e430e9bb445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=A0=95=EB=AF=BC?= Date: Sat, 12 Oct 2024 16:27:14 +0900 Subject: [PATCH 5/5] =?UTF-8?q?feat:=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=20=EB=82=B4=20useMutation=20=ED=9B=85=20depreacted=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/shared/hooks/useMutation.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/shared/hooks/useMutation.ts b/frontend/src/shared/hooks/useMutation.ts index f332c45f..ecdb990c 100644 --- a/frontend/src/shared/hooks/useMutation.ts +++ b/frontend/src/shared/hooks/useMutation.ts @@ -4,6 +4,9 @@ import { useLoginModalByError } from '@/features/auth/hooks/useLoginModalByError import AuthError from '@/shared/remotes/AuthError'; import type { ErrorResponse } from '../types/errorResponse'; +/** + * @deprecated react-query의 useMutation 훅을 사용해주세요. + */ // eslint-disable-next-line export const useMutation = (mutateFn: (...params: P) => Promise) => { const [data, setData] = useState(null);