Skip to content

Commit

Permalink
Refactor: 피드페이지 리팩토링 (#193)
Browse files Browse the repository at this point in the history
* Design: 피드페이지 - 카테고리 스켈레톤 UI 수정

* Style: 주석 정리

* Style: 카테고리 컴포넌트 'use client' 제거

* Design: 피드페이지 - 프로필 컴포넌트 스켈레톤 UI 수정 및 isLoading으로 속성 변경

* Refactor: 모달 버튼 공통컴포넌트로 적용, 페이지 이동 Link 컴포넌트로 변경

* Fix: 다국어 기능 팔로우 -> 팔로워로 수정

* Style: 변수이름 알맞게 수정 및 src 표기 수정

* Design: 피드페이지 - 그리드컨텐츠 리스트 스켈레톤 UI 수정

* Style: 불필요한 파일 삭제, 일부 컴포넌트 컨벤션 수정

* Feat: 팔로우 버튼 disabled 적용

* Refactor: 피드페이지 리스트전체조회 쿼리 staleTime 설정, unmount시 쿼리초기화 로직 제거

* Chore: 리액트쿼리 devtools 적용

* Feat: 리스트 생성, 수정, 삭제 시 리스트 전체조회 쿼리 무효화(invalidateQueries) 로직 추가

* Refactor: 카테고리 조회 staleTime 설정, 스켈레톤 적용 시 isLoading 속성으로 변경
  • Loading branch information
ParkSohyunee authored and Eugene-A-01 committed Mar 15, 2024
1 parent c12159e commit 8926abe
Show file tree
Hide file tree
Showing 17 changed files with 98 additions and 140 deletions.
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 + ''] });
},
});

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 + ''],
});
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, // 카테고리는 자주 변하는 데이터가 아니므로
});

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

0 comments on commit 8926abe

Please sign in to comment.