Skip to content

Commit

Permalink
Refactor/#573 useQuery를 훅으로 감싸는 방식에서 queryOptions를 활용하는 방식으로 변경 (#574)
Browse files Browse the repository at this point in the history
* refactor: comments 쿼리를 쿼리 옵션 기반으로 리팩토링

* refactor: songDetailEntries 쿼리를 쿼리 옵션 기반으로 리팩토링

* refactor: extraPrevSongDetails, extraNextSongDetails 인피니트 쿼리를 쿼리 옵션 기반으로 리팩토링

* refactor: mutate 옵션이 드러나도록 컴포넌트에서 직접 사용하도록 변경

* feat: 프로젝트 내 useMutation 훅 depreacted 처리
  • Loading branch information
cruelladevil authored Oct 16, 2024
1 parent ed0666b commit ded29ab
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 67 deletions.
14 changes: 9 additions & 5 deletions frontend/src/features/comments/components/CommentForm.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -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();

Expand Down
5 changes: 3 additions & 2 deletions frontend/src/features/comments/components/CommentList.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -41,7 +42,7 @@ const CommentList = ({ songId, partId }: CommentListProps) => {
</BottomSheet>
));

const { comments } = useCommentsQuery(songId, partId);
const { data: comments } = useQuery(commentsQueryOptions(songId, partId));

if (!comments) {
return null;
Expand Down
24 changes: 4 additions & 20 deletions frontend/src/features/comments/queries/index.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,8 @@
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { getComments, postComment } from '../remotes/comments';
import { queryOptions } from '@tanstack/react-query';
import { getComments } 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();

const { mutate: postNewComment, ...mutations } = useMutation({
mutationFn: postComment,
onSuccess: (_, { songId, partId }) => {
client.invalidateQueries({ queryKey: ['comments', songId, partId] });
},
});

return { postNewComment, mutations };
};
27 changes: 17 additions & 10 deletions frontend/src/features/songs/hooks/useExtraSongDetail.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
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';

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<IntersectionObserver | null>(null);
const nextObserverRef = useRef<IntersectionObserver | null>(null);
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/features/songs/hooks/useSongDetailEntries.ts
Original file line number Diff line number Diff line change
@@ -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<HTMLDivElement> = useCallback((dom) => {
if (dom !== null) dom.scrollIntoView({ behavior: 'instant', block: 'start' });
Expand Down
33 changes: 8 additions & 25 deletions frontend/src/features/songs/queries/index.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
import { useInfiniteQuery, useQuery } from '@tanstack/react-query';
import { infiniteQueryOptions, queryOptions } from '@tanstack/react-query';
import {
getExtraNextSongDetails,
getExtraPrevSongDetails,
getSongDetailEntries,
} 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,
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,
Expand All @@ -30,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 };
};
3 changes: 3 additions & 0 deletions frontend/src/shared/hooks/useMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = <T, P extends any[]>(mutateFn: (...params: P) => Promise<T>) => {
const [data, setData] = useState<T | null>(null);
Expand Down

0 comments on commit ded29ab

Please sign in to comment.