Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor/#573 useQuery를 훅으로 감싸는 방식에서 queryOptions를 활용하는 방식으로 변경 #574

Merged
merged 5 commits into from
Oct 16, 2024
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 All @@ -34,7 +41,7 @@
}

prevObserverRef.current?.disconnect();
}, []);

Check warning on line 44 in frontend/src/features/songs/hooks/useExtraSongDetail.ts

View workflow job for this annotation

GitHub Actions / test

React Hook useCallback has a missing dependency: 'fetchExtraPrevSongDetails'. Either include it or remove the dependency array

const getExtraNextSongDetailsOnObserve: React.RefCallback<HTMLDivElement> = useCallback((dom) => {
if (dom !== null) {
Expand All @@ -45,7 +52,7 @@
}

nextObserverRef.current?.disconnect();
}, []);

Check warning on line 55 in frontend/src/features/songs/hooks/useExtraSongDetail.ts

View workflow job for this annotation

GitHub Actions / test

React Hook useCallback has a missing dependency: 'fetchExtraNextSongDetails'. Either include it or remove the dependency array

return {
extraPrevSongDetails,
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
Loading