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: 피드페이지 리팩토링 #193

Merged
merged 14 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 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
2 changes: 2 additions & 0 deletions src/app/_context/CommonProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { ReactNode } from 'react';
import { CookiesProvider } from 'react-cookie';

Expand All @@ -10,6 +11,7 @@ export default function CommonProvider({ children }: { children: ReactNode }) {
return (
<QueryClientProvider client={queryClient}>
<CookiesProvider>{children}</CookiesProvider>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default function OpenBottomSheetButton({ listId, isCollaborator }: OpenBo
const deleteCommentMutation = useMutation({
mutationFn: () => deleteList(listId),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.getAllList, user.id] });
queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.getAllList, user.id + ''] });
Copy link
Contributor

Choose a reason for hiding this comment

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

소현님, 공백 추가하신 이유가 궁금합니다!! 뒤에 공백을 추가하지 않으면 인식되지 않는 걸까요??

Copy link
Contributor Author

Choose a reason for hiding this comment

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

소현님, 공백 추가하신 이유가 궁금합니다!! 뒤에 공백을 추가하지 않으면 인식되지 않는 걸까요??

서영님, 맞습니다🥰 getAllList의 쿼리키 중 userId가 string이기 때문에 동일한 키로 인식하기 위해 number타입의 user.id를 문자열로 변환하기 위한 방법을 넣은 것입니다! 문자열로 변환하기 위한 여러 방법이 있겠지만 저는 위처럼 작성하는 편입니다,
혹시 추가로 궁금하신 점 있으시면 말씀 부탁드립니다!!

Copy link
Contributor

Choose a reason for hiding this comment

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

@ParkSohyunee 소현님! 늦은 확인 죄송합니다..!! 🥹 쿼리 무효화 해주신 부분 잘 확인했습니다! 정말 감사합니다!! 🙇‍♀️

},
});

Expand Down
6 changes: 5 additions & 1 deletion src/app/list/[listId]/edit/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { useEffect, useState } from 'react';
import { FieldErrors, FormProvider, useForm } from 'react-hook-form';
import { useMutation, useQuery } from '@tanstack/react-query';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useRouter, useParams } from 'next/navigation';

import CreateItem from '@/app/list/create/_components/CreateItem';
Expand All @@ -20,6 +20,7 @@ export type FormErrors = FieldErrors<ListEditType>;

export default function EditPage() {
const router = useRouter();
const queryClient = useQueryClient();
const param = useParams<{ listId: string }>();
const { user } = useUser();

Expand Down Expand Up @@ -144,6 +145,9 @@ export default function EditPage() {
} = useMutation({
mutationFn: updateList,
onSettled: () => {
queryClient.invalidateQueries({
queryKey: [QUERY_KEYS.getAllList, user.id + ''],
Copy link
Contributor

Choose a reason for hiding this comment

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

수정에서는 생성페이지에서 사용했던 키인
formatData().listData.collaboratorIds.length === 0 ? 'my' : 'collabo',
이 부분은 따로 필요 없을까요??

Copy link
Contributor Author

Choose a reason for hiding this comment

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

수정에서는 생성페이지에서 사용했던 키인 formatData().listData.collaboratorIds.length === 0 ? 'my' : 'collabo', 이 부분은 따로 필요 없을까요??

서영님 맞습니다~!, 쿼리키를 다 넣을 수도 있지만 수정페이지에서는 타입도 변할 가능성이 있기 때문에 (예를 들어, 마이리스트에서 수정할때 콜라보를 넣어서 콜라보를 넣는 경우 또는 그 반대의 경우 등) 정확한 쿼리키를 넣으면 그 반대의 경우도 넣어줘야 하므로 여러가지 조건을 고려해야 했습니다, 그래서 수정할때는 유저아이디에 해당하는 리스트를 다시 무효화하는 방법이 더 맞다고 판단하여 적용했습니다!✍️

});
router.replace(`/list/${param?.listId}`);
},
});
Expand Down
13 changes: 12 additions & 1 deletion src/app/list/create/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,26 @@

import { useState } from 'react';
import { FieldErrors, FormProvider, useForm } from 'react-hook-form';
import { useMutation } from '@tanstack/react-query';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useRouter } from 'next/navigation';

import CreateItem from '@/app/list/create/_components/CreateItem';
import CreateList from '@/app/list/create/_components/CreateList';
import { ItemImagesType, ListCreateType } from '@/lib/types/listType';
import toasting from '@/lib/utils/toasting';
import toastMessage from '@/lib/constants/toastMessage';
import { QUERY_KEYS } from '@/lib/constants/queryKeys';
import createList from '@/app/_api/list/createList';
import uploadItemImages from '@/app/_api/list/uploadItemImages';
import { useLanguage } from '@/store/useLanguage';
import { useUser } from '@/store/useUser';

export type FormErrors = FieldErrors<ListCreateType>;

export default function CreatePage() {
const { language } = useLanguage();
const { user: userMeData } = useUser();
const queryClient = useQueryClient();
const [step, setStep] = useState<'list' | 'item'>('list');
const router = useRouter();

Expand Down Expand Up @@ -124,6 +128,13 @@ export default function CreatePage() {
imageFileList: formatData().imageFileList,
});
}
queryClient.invalidateQueries({
queryKey: [
QUERY_KEYS.getAllList,
userMeData.id + '',
formatData().listData.collaboratorIds.length === 0 ? 'my' : 'collabo',
],
});
router.replace(`/list/${data.listId}`);
},
onError: () => {
Expand Down
7 changes: 7 additions & 0 deletions src/app/user/[userId]/_components/Categories.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ export const container = style({
},
});

export const skeletonContainer = style({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
gap: '1.5rem',
});

export const button = style({
padding: '0.8rem 1.2rem',

Expand Down
21 changes: 9 additions & 12 deletions src/app/user/[userId]/_components/Categories.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,22 @@
'use client';

/**
TODO
- [ ] 클릭했을때 로직 (상위요소에 핸들러 고민) (리팩토링)
*/

import { useQuery } from '@tanstack/react-query';
import { Skeleton } from '@mui/material';

import * as styles from './Categories.css';

import getCategories from '@/app/_api/category/getCategories';
import { CategoryType } from '@/lib/types/categoriesType';
import { QUERY_KEYS } from '@/lib/constants/queryKeys';

import CategoriesSkeleton from './CategoriesSkeleton';

interface CategoriesProps {
handleFetchListsOnCategory: (category: string) => void;
selectedCategory: string;
}

export default function Categories({ handleFetchListsOnCategory, selectedCategory }: CategoriesProps) {
const { data, isFetching } = useQuery<CategoryType[]>({
const { data, isLoading } = useQuery<CategoryType[]>({
queryKey: [QUERY_KEYS.getCategories],
queryFn: getCategories,
staleTime: Infinity, // 카테고리는 자주 변하는 데이터가 아니므로
Copy link
Contributor

Choose a reason for hiding this comment

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

👍👍👍👍👍

});

const handleChangeCategory = (category: string) => () => {
Expand All @@ -32,8 +25,12 @@ export default function Categories({ handleFetchListsOnCategory, selectedCategor

return (
<div className={styles.container}>
{isFetching ? (
<CategoriesSkeleton />
{isLoading ? (
<div className={styles.skeletonContainer}>
{new Array(4).fill(0).map((_, index) => (
<Skeleton key={index} variant="rounded" width={100} height={35} animation="wave" />
))}
</div>
) : (
data?.map((category) => (
<button
Expand Down
15 changes: 0 additions & 15 deletions src/app/user/[userId]/_components/CategoriesSkeleton.tsx

This file was deleted.

7 changes: 7 additions & 0 deletions src/app/user/[userId]/_components/Content.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ export const cards = style({
textAlign: 'center',
});

export const gridSkeletonContainer = style({
display: 'grid',
gridTemplateColumns: 'repeat(2, 1fr)',
rowGap: '1.6rem',
columnGap: '1.2rem',
});

export const nodataContainer = style({
minHeight: '250px',
});
Expand Down
25 changes: 10 additions & 15 deletions src/app/user/[userId]/_components/Content.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
'use client';

import Link from 'next/link';
import { useEffect, useMemo, useState } from 'react';
import { useInfiniteQuery, useQuery, useQueryClient } from '@tanstack/react-query';
import { useMemo, useState } from 'react';
import { useInfiniteQuery, useQuery } from '@tanstack/react-query';
import { MasonryGrid } from '@egjs/react-grid';
import { Skeleton } from '@mui/material';

import * as styles from './Content.css';

import Card from './Card';
import Categories from './Categories';
import NoDataComponent from '@/components/NoData/NoDataComponent';

import getUserOne from '@/app/_api/user/getUserOne';
import getAllList from '@/app/_api/list/getAllList';
Expand All @@ -18,8 +20,6 @@ import { UserType } from '@/lib/types/userProfileType';
import { AllListType } from '@/lib/types/listType';

import useIntersectionObserver from '@/hooks/useIntersectionObserver';
import MasonryGridSkeleton from './MasonryGridSkeleton';
import NoDataComponent from '@/components/NoData/NoDataComponent';
import { userLocale } from '@/app/user/locale';
import { useLanguage } from '@/store/useLanguage';

Expand All @@ -32,7 +32,6 @@ const DEFAULT_CATEGORY = 'entire';

export default function Content({ userId, type }: ContentProps) {
const { language } = useLanguage();
const queryClient = useQueryClient();
const [selectedCategory, setSelectedCategory] = useState(DEFAULT_CATEGORY);

const { data: userData } = useQuery<UserType>({
Expand All @@ -52,6 +51,7 @@ export default function Content({ userId, type }: ContentProps) {
},
initialPageParam: null,
getNextPageParam: (lastPage) => (lastPage.hasNext ? lastPage.cursorUpdatedDate : null),
staleTime: 1000 * 60 * 5, // 5분 설정
});

const lists = useMemo(() => {
Expand All @@ -72,15 +72,6 @@ export default function Content({ userId, type }: ContentProps) {
setSelectedCategory(category);
};

useEffect(() => {
return () => {
queryClient.removeQueries({
queryKey: [QUERY_KEYS.getAllList, userId, type, selectedCategory],
exact: true,
});
};
}, [queryClient, selectedCategory, type, userId]);

return (
<div className={styles.container}>
<div className={styles.options}>
Expand All @@ -101,7 +92,11 @@ export default function Content({ userId, type }: ContentProps) {
)}
<div className={styles.cards}>
{isLoading ? (
<MasonryGridSkeleton />
<div className={styles.gridSkeletonContainer}>
{new Array(4).fill(0).map((_, index) => (
<Skeleton key={index} variant="rounded" height={200} animation="wave" />
))}
</div>
) : (
<MasonryGrid className="container" gap={16} defaultDirection={'end'} align={'start'} column={2}>
{lists.map((list) => (
Expand Down
6 changes: 2 additions & 4 deletions src/app/user/[userId]/_components/FollowButton.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
'use client';

import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { AxiosError } from 'axios';

Expand All @@ -26,9 +24,8 @@ interface FollowButtonProps {
}

export default function FollowButton({ isFollowed, userId }: FollowButtonProps) {
const { language } = useLanguage();

const queryClient = useQueryClient();
const { language } = useLanguage();
const { user: userMe } = useUser();
const { isOn, handleSetOff, handleSetOn } = useBooleanOutput();

Expand Down Expand Up @@ -85,6 +82,7 @@ export default function FollowButton({ isFollowed, userId }: FollowButtonProps)
<button
className={`${isFollowed ? styles.variant.gray : styles.variant.primary}`}
onClick={handleFollowUser(isFollowed)}
disabled={followUser.isPending || deleteFollowingUser.isPending}
>
{isFollowed ? userLocale[language].cancelFollow : userLocale[language].follow}
</button>
Expand Down
15 changes: 0 additions & 15 deletions src/app/user/[userId]/_components/MasonryGridSkeleton.tsx

This file was deleted.

12 changes: 12 additions & 0 deletions src/app/user/[userId]/_components/Profile.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@ export const profileContainer = style({
},
});

export const skeletonProfileContainer = style({
paddingBottom: '3rem',
display: 'flex',
alignItems: 'center',
gap: '1.2rem',
});

export const skeletonTextContainer = style({
display: 'flex',
flexDirection: 'column',
});

export const icon = style({
cursor: 'pointer',
});
Expand Down
Loading