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: useSuspenseQuery 적용 및 훅 리팩터링 #326

Merged
merged 20 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend/src/components/@common/Calendar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useState } from 'react';
import { AlertSpan, Button, CalendarBox, DaysBox, HeaderBox, Wrapper } from './Calendar.style';
import useCalendar from 'hooks/useCalendar';
import { convertDateKorYear, getDateToString, getDayInfo, getDaysBetween } from 'utils/date';
import { DateValidate } from 'utils/validate';
import { DAYS_OF_THE_WEEK } from 'constants/index';
import ArrowLeft from '../Icons/ArrowLeft';
import ArrowRight from '../Icons/ArrowRight';
import DaySmallBox from './DaySmallBox';
import useCalendar from './useCalendar';

interface CalendarProps {
selectedDate: Date | null;
Expand Down
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C

Calendar > useCalendar 보다 hooks 폴더로 감싸고 넣는것은 어떻게 생각하시나요?
Calendar > hooks > useCalendar

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋습니다!

File renamed without changes.
23 changes: 0 additions & 23 deletions frontend/src/components/@common/Spinner/Spinner.stories.tsx

This file was deleted.

30 changes: 0 additions & 30 deletions frontend/src/components/@common/Spinner/Spinner.style.ts

This file was deleted.

26 changes: 0 additions & 26 deletions frontend/src/components/@common/Spinner/index.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Meta, StoryObj } from '@storybook/react';
import { Suspense } from 'react';
import LoadingSpinner from 'components/@common/Spinner';
import Loading from 'pages/Loading';
import PetDetails from '.';

const meta: Meta<typeof PetDetails> = {
Expand All @@ -12,7 +12,7 @@ const meta: Meta<typeof PetDetails> = {

decorators: [
(Story) => (
<Suspense fallback={<LoadingSpinner />}>
<Suspense fallback={<Loading />}>
<Story />
</Suspense>
),
Expand Down
32 changes: 32 additions & 0 deletions frontend/src/components/petPlant/Timeline/Skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {
DayArea,
DayHeader,
SkeletonItem,
SkeletonItemContent,
TimelineArea,
YearHeader,
} from './Timeline.style';

interface SkeletonProps {
hasYearHeader?: boolean;
}

const Skeleton = ({ hasYearHeader }: SkeletonProps) => (
<>
{hasYearHeader && <YearHeader />}
{Array(10)
.fill(null)
.map((_, index) => (
<DayArea key={index}>
<DayHeader />
<TimelineArea>
<SkeletonItem>
<SkeletonItemContent />
</SkeletonItem>
</TimelineArea>
</DayArea>
))}
</>
);

export default Skeleton;
29 changes: 7 additions & 22 deletions frontend/src/components/petPlant/Timeline/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import {
Plant,
PlantImage,
Sensor,
SkeletonItem,
SkeletonItemContent,
Spot,
TimelineArea,
Wrapper,
Expand All @@ -23,6 +21,7 @@ import useYearList from 'hooks/queries/history/useYearList';
import useIntersectionRef from 'hooks/useIntersectionRef';
import Sprout from 'assets/sprout.svg';
import TimelineItemList from '../TimelineItemList';
import Skeleton from './Skeleton';

interface TimelineProps {
petPlantId: PetPlantDetails['id'];
Expand All @@ -32,8 +31,8 @@ interface TimelineProps {
const Timeline = ({ petPlantId, filter }: TimelineProps) => {
const {
data: yearList,
isSuccess,
hasNextPage,
isLoading,
isFetchingNextPage,
fetchNextPage,
} = useYearList(Number(petPlantId), filter);
Expand All @@ -48,7 +47,7 @@ const Timeline = ({ petPlantId, filter }: TimelineProps) => {
<Plant>
<PlantImage src={Sprout} alt="타임라인 꼭대기" />
</Plant>
{yearList &&
{isSuccess ? (
yearList.map(([year, monthList]) => (
<YearArea key={year}>
<YearHeader>{year}</YearHeader>
Expand All @@ -70,26 +69,12 @@ const Timeline = ({ petPlantId, filter }: TimelineProps) => {
</MonthArea>
))}
</YearArea>
))}
{(isLoading || isFetchingNextPage) && (
<>
{isLoading && <YearHeader />}
{Array(10)
.fill(null)
.map((_, index) => (
<DayArea key={index}>
<DayHeader />
<TimelineArea>
<SkeletonItem>
<SkeletonItemContent />
</SkeletonItem>
</TimelineArea>
</DayArea>
))}
</>
))
) : (
<Skeleton hasYearHeader />
)}
{isFetchingNextPage ? <Skeleton /> : <Sensor ref={intersectionRef} />}
{!hasNextPage && <Earth />}
{!isFetchingNextPage && <Sensor ref={intersectionRef} />}
</Wrapper>
);
};
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/reminder/MonthBox/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReminderExtendType } from 'types/reminder';
import type { ReminderExtendType } from 'types/reminder';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

import { MonthReminderBox, MonthTitle } from './MonthBox.style';
import CardBox from '../CardBox';

Expand Down
7 changes: 3 additions & 4 deletions frontend/src/hooks/queries/auth/useCheckSessionId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@ import AuthAPI from 'apis/auth';
import noRetryIfUnauthorized from 'utils/noRetryIfUnauthorized';
import throwOnInvalidStatus from 'utils/throwOnInvalidStatus';

const useCheckSessionId = (suspense = true) => {
return useQuery<null, Error | StatusError>({
const useCheckSessionId = (throwOnError = true) =>
useQuery<null, Error | StatusError>({
queryKey: ['checkSessionId'],
queryFn: async () => {
const response = await AuthAPI.checkSessionId();
throwOnInvalidStatus(response);
return null;
},

throwOnError,
retry: noRetryIfUnauthorized,
suspense,
});
};

export default useCheckSessionId;
10 changes: 3 additions & 7 deletions frontend/src/hooks/queries/auth/useLogin.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
import { useQuery } from '@tanstack/react-query';
import { useSuspenseQuery } from '@tanstack/react-query';
import AuthAPI from 'apis/auth';
import throwOnInvalidStatus from 'utils/throwOnInvalidStatus';

const useLogin = (code: string) => {
return useQuery<null, Error, void>({
const useLogin = (code: string) =>
useSuspenseQuery<null, Error, void>({
queryKey: ['getSession', code],
queryFn: async () => {
const response = await AuthAPI.getSessionId(code);

throwOnInvalidStatus(response);

return null;
},
suspense: true,
});
};

export default useLogin;
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { DictionaryPlant, Season, SeasonKor } from 'types/dictionaryPlant';
import { useQuery } from '@tanstack/react-query';
import { useSuspenseQuery } from '@tanstack/react-query';
import DictionaryPlantAPI, { DICTIONARY_PLANT_URL } from 'apis/dictionaryPlant';
import { SEASONS } from 'constants/index';

Expand All @@ -15,7 +15,7 @@ const initialWaterOptions: DictionaryPlantExtendCycles['waterOptions'] = {
};

const useDictionaryPlantDetail = (id: number) =>
useQuery<DictionaryPlant, Error, DictionaryPlantExtendCycles>({
useSuspenseQuery<DictionaryPlant, Error, DictionaryPlantExtendCycles>({
queryKey: [DICTIONARY_PLANT_URL, 'detail', id],

queryFn: async () => {
Expand All @@ -27,8 +27,6 @@ const useDictionaryPlantDetail = (id: number) =>
},

staleTime: Infinity,
suspense: true,
throwOnError: true,
select: (data) => {
const { waterCycle } = data;

Expand Down
5 changes: 2 additions & 3 deletions frontend/src/hooks/queries/history/useYearList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import throwOnInvalidStatus from 'utils/throwOnInvalidStatus';
import useCheckSessionId from '../auth/useCheckSessionId';

const useYearList = (petPlantId: PetPlantDetails['id'], filter: HistoryType[] = []) => {
const { isSuccess } = useCheckSessionId();
useCheckSessionId();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

R

petPlant의 hooks 에서는 useCheckSessionId를 사용하지 않았는데 여기서는 사용한 이유가 있을까요???

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

훅에서는 useCheckSessionId가 없어도 될 것 같네요!


return useInfiniteQuery<
HistoryResponse,
Expand All @@ -32,7 +32,7 @@ const useYearList = (petPlantId: PetPlantDetails['id'], filter: HistoryType[] =
return data;
},

defaultPageParam: 0,
initialPageParam: 0,
getNextPageParam: ({ hasNext }, _allPages, lastPageParam) => {
return hasNext ? lastPageParam + 1 : undefined;
},
Expand All @@ -45,7 +45,6 @@ const useYearList = (petPlantId: PetPlantDetails['id'], filter: HistoryType[] =
},

retry: noRetryIfUnauthorized,
enabled: isSuccess,
refetchOnWindowFocus: false,
placeholderData: keepPreviousData,
gcTime: 0,
Expand Down
10 changes: 2 additions & 8 deletions frontend/src/hooks/queries/petPlant/usePetPlantCardList.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import type { DataResponse } from 'types/DataResponse';
import type { PetPlantItem } from 'types/petPlant';
import { useQuery } from '@tanstack/react-query';
import { useSuspenseQuery } from '@tanstack/react-query';
import PetPlantAPI, { PET_PLANT_URL } from 'apis/petPlant';
import noRetryIfUnauthorized from 'utils/noRetryIfUnauthorized';
import throwOnInvalidStatus from 'utils/throwOnInvalidStatus';
import useCheckSessionId from '../auth/useCheckSessionId';

const usePetPlantCardList = () => {
const { isSuccess } = useCheckSessionId();

return useQuery<DataResponse<PetPlantItem[]>, Error, PetPlantItem[]>({
return useSuspenseQuery<DataResponse<PetPlantItem[]>, Error, PetPlantItem[]>({
queryKey: [PET_PLANT_URL, 'list'],
queryFn: async () => {
const response = await PetPlantAPI.getList();
Expand All @@ -20,10 +17,7 @@ const usePetPlantCardList = () => {
},

select: ({ data }) => data,

suspense: true,
retry: noRetryIfUnauthorized,
enabled: isSuccess,
});
};

Expand Down
Loading