[๐Ÿ’ป ์ฝ”๋“œ์Šคํ…Œ์ด์ธ  FE 44๊ธฐ]main-project - 11์ผ์ฐจ

JiEunยท2023๋…„ 7์›” 12์ผ
0
post-thumbnail

๋งˆ์ดํŽ˜์ด์ง€ ๋ฆฌ์ŠคํŠธ ์กฐํšŒํ•˜๊ธฐ

๐Ÿค” ์ด์Šˆ์‚ฌํ•ญ

๋งˆ์ดํŽ˜์ด์ง€ ๋ฆฌ์ŠคํŠธ ์กฐํšŒ ์ž‘์—…์„ ์ง„ํ–‰ํ–ˆ๋‹ค.
์ผ์ •, ์ฆ๊ฒจ์ฐพ๊ธฐ ํƒญ๋ฉ”๋‰ด๊ฐ€ ์žˆ๊ณ 
ํ•˜๋‹จ์—๋Š” ๋ณธ์ธ ์ž‘์„ฑํ•œ ์ผ์ •, ์ฆ๊ฒจ์ฐพ๊ธฐํ•œ ์นด๋“œ๋ฅผ ๋ชจ์•„ ๋‘์—ˆ๋‹ค.

๋งˆ์ดํŽ˜์ด์ง€ ๋ฆฌ์ŠคํŠธ ์กฐํšŒ๋Š” ๋‹คํ–‰ํžˆ ์ปค๋ฎค๋‹ˆํ‹ฐ ํŽ˜์ด์ง€์™€ ๊ฑฐ์˜ ๋™์ผํ•˜๊ธฐ ๋•Œ๋ฌธ์—
์กฐ๊ฑด์ด๋‚˜ props๋งŒ ์ˆ˜์ •ํ•˜๋ฉด ๋œ๋‹ค.

์—ฌ๊ธฐ์„œ ๋ช‡๊ฐ€์ง€ ์ด์Šˆ ์‚ฌํ•ญ์ด ์žˆ์—ˆ๋‹ค.

  1. ๋‚จ์˜ ์ฝ”๋“œ ๊ณ ์น˜๋Š”๊ฒŒ ๋” ํž˜๋“ค๋‹ค...
  2. ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ํƒ€์ž…, eslint ์—๋Ÿฌ ์ง„์งœ ๋ณต๋ณ‘์ด๋‹ค...ใ… 

1. ๋‚จ์˜ ์ฝ”๋“œ ๊ณ ์น˜๋Š”๊ฒŒ ๋” ํž˜๋“ค๋‹ค...

์›๋ž˜ ๋งŒ๋“ค์–ด์ ธ ์žˆ๋˜ ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์‰ฌ์šธ ๊ฑฐ ๊ฐ™์ง€๋งŒ
์˜คํžˆ๋ ค ๋” ํž˜๋“ค๋‹ค.

๊ฐ๊ฐ ์–ด๋–ค ๊ธฐ๋Šฅ์„ ํ•˜๊ณ  ์žˆ๋Š”์ง€ ํŒŒ์•…ํ•ด์•ผ ํ•˜๊ณ 
์–ด๋–ค props๋ฅผ ๋‚ด๋ ค์ฃผ๋Š”์ง€ ๋“ฑ ์ฝ”๋“œ ๋ถ„์„ํ•˜๋Š” ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ ธ๋‹ค.

๋˜ํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ ํŽ˜์ด์ง€๋Š” ํ•˜๋‚˜์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์กฐํšŒํ•˜๋ฉด ๋˜์ง€๋งŒ
๋งˆ์ดํŽ˜์ด์ง€๋Š” ๋ณธ์ธ ์ผ์ •, ์ฆ๊ฒจ์ฐพ๊ธฐ ํ•œ ์˜์—ญ 2๊ฐ€์ง€๊ฐ€ ์žˆ๋Š” ์  ๋ถ€ํ„ฐ ๋‹ฌ๋ž๋‹ค.

์ž‘์—… ํ•˜๋ฉด์„œ ๋ง‰ํžˆ๋Š” ๋ถ€๋ถ„์€ ์ž‘์—…ํ•˜์‹  ํŒ€์› ๋ถ„๊ป˜ ๋ฐ”๋กœ๋ฐ”๋กœ ์—ฌ์ญค ๋ณด์•˜๋‹ค.

<FilterTab
  content="์ตœ์‹ ์ˆœ"
  selectTab={selectTab}
  tab="Newest"
  onClick={setTab}
  />
<FilterTab
  content="์ข‹์•„์š”์ˆœ"
  selectTab={selectTab}
  tab="Like"
  onClick={setTab}
  />

ํƒญ๋ฉ”๋‰ด ์˜์—ญ์ด ์ด๋Ÿฐ์‹์œผ๋กœ ๋˜์–ด ์žˆ์–ด selectTab์œผ๋กœ ๊ตฌ๋ถ„์„ ํ•˜๋Š”๊ฑฐ ๊ฐ™์•˜๋‹ค.
์ด๋ถ€๋ถ„์€ ๋‹คํ–‰ํžˆ ๊ธˆ๋ฐฉ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

<FilterTab
  content="์ผ์ •"
  selectTab={selectTab}
  tab="First"
  onClick={setTab}
  />
<FilterTab
  content="์ฆ๊ฒจ์ฐพ๊ธฐ"
  selectTab={selectTab}
  tab="Second"
  onClick={setTab}
  />

๊ธฐ์กด์— ์žˆ๋˜๊ฑฐ ์ฒ˜๋Ÿผ ํŠน์ • ๋‹จ์–ด๋กœ ์ฃผ์ง€ ์•Š๊ณ 
์ฒซ๋ฒˆ์งธ, ๋‘๋ฒˆ์งธ, ... ๋„ค์ด๋ฐ์„ ๋ณ€๊ฒฝํ•ด ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ˆ˜์ •ํ–ˆ๋‹ค.

์นด๋“œ ์ปดํฌ๋„ŒํŠธ๋„ ๋งˆ์ดํŽ˜์ด์ง€๋Š” 2๊ฐ€์ง€๋ฅผ ์กฐํšŒํ•ด์•ผ ํ•ด์„œ
selectTab์ด First์ธ ๊ฒƒ๊ณผ ์•„๋‹Œ ๊ฒƒ์„ ์กฐ๊ฑด์œผ๋กœ ์ค˜์„œ ๋‚˜๋ˆ  ์ฃผ์—ˆ๋‹ค.

{selectTab === 'First'
  ? memberCourseList?.map((post: MypCourseSummaryT) => (
    <ContensCard
      ...
    </ContensCard>
  ))
  : memberBookmarkedList?.map((post: MyBookMarkSummaryT) => (
     <ContensCard
      ...
    </ContensCard>
  ))}

๋‹คํ–‰ํžˆ ๋ฆฌ์ŠคํŠธ ์กฐํšŒํ•˜๋Š” ๊ฑด ๊ธˆ๋ฐฉ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ์ง€๋งŒ,
์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•˜๊ณ  ์ดํ•ดํ•˜๋Š”๋ฐ ๋งŽ์€ ์‹œ๊ฐ„์ด ํ•„์š” ํ–ˆ๊ณ 
๋ง‰ํž ๋•Œ ๋งˆ๋‹ค ์ž‘์—… ํ•˜์‹  ํŒ€์› ๋ถ„๊ป˜ ์—ฌ์ญค๋ด์•ผ ํ–ˆ์—ˆ๋‹ค.

2. ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ํƒ€์ž…, eslint ์—๋Ÿฌ ์ง„์งœ ๋ณต๋ณ‘์ด๋‹ค...ใ… 

์ง„์งœ... ๊ธฐ๋Šฅ ๊ตฌํ˜„์€ ์™„๋ฃŒ ํ–ˆ๋Š”๋ฐ
๋นจ๊ฐ„์ค„์ด ๋‚˜๋ฅผ ํž˜๋“ค๊ฒŒ ํ–ˆ๋‹ค.

๋ช‡ ๊ฐœ๋Š” ์ค„๋ฐ”๊ฟˆ ํ•ด์„œ ๊ธˆ๋ฐฉ ํ•ด๊ฒฐ ํ•  ์ˆ˜ ์žˆ์—ˆ์ง€๋งŒ
๊ฐ„ํ˜น ํ•ด๋‹น ๊ฐ’์€ undefined๊ฐ€ ๋“ค์–ด ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ๋“ฑ
์• ๋งคํ•œ ์˜ค๋ฅ˜๋ฅผ ๋ฑ‰์–ด ๋ƒˆ๋‹ค.

const { data: userMemData } = useQuery(['userInof'], () => GetMyList());

์ฒ˜์Œ์—” useQuery๋ฅผ ์ด์šฉํ•ด ์„œ๋ฒ„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๊ณ  ํ–ˆ๋‹ค.
๊ทธ๋žฌ๋”๋‹ˆ data๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋‚ฌ์—ˆ๋‹ค.

console.log(userMemData?.data?.memberBookmarkedList);

์ด๋Ÿฐ์‹์œผ๋กœ ์˜ต์…”๋„ ์„ค์ •๋„ ํ•ด์ฃผ๊ณ  ํƒ€์ž… ์„ค์ •๋„ ํ•ด๋ดค๋Š”๋ฐ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ–ˆ๋‹ค.

ํŒ€์› ๋ถ„์˜ ๋„์›€์„ ๋ฐ›์•˜๊ณ 
useQuery๋Š” ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ’์„ ๋ฐ›์•„์˜ค๊ธฐ๋„ ์ „์— ๋ถˆ๋Ÿฌ์™€์„œ ๊ทธ๋Ÿฐ๊ฑฐ ๊ฐ™๋‹ค๊ณ  ํ•˜์…จ๋‹ค.
๋ฐ์ดํ„ฐ๋ฅผ ์ „์—ญ์œผ๋กœ ์ €์žฅํ•ด์„œ ๋ถˆ๋Ÿฌ ๋ณด๋ฉด ์–ด๋– ๋ƒ๊ณ  ๋ง์”€ํ•ด ์ฃผ์…จ๋‹ค.

import { PayloadAction, createSlice } from '@reduxjs/toolkit';

import {
  MypCourseSummaryT,
  MyBookMarkSummaryT,
  MypSummaryT,
} from '../types/apitype';

const initialState: MypSummaryT = {
  memberCourseList: [
    {
      courseContent: '',
      courseDday: '',
      courseId: -1,
      courseLikeCount: 0,
      courseThumbnail: '',
      courseTitle: '',
      courseUpdatedAt: '',
      courseViewCount: 0,
      isPosted: false,
      memberNickname: '',
    },
  ],
  memberBookmarkedList: [
    {
      courseId: -1,
      courseLikeCount: 0,
      courseThumbnail: '',
      courseTitle: '',
      courseUpdatedAt: '',
      courseViewCount: 0,
      likeStatus: false,
      memberNickname: '',
      postContent: '',
      postCreatedAt: '',
      postId: -1,
      tags: [''],
    },
  ],
};

const myInfoDataListSlice = createSlice({
  name: 'myInfoData',
  initialState,
  reducers: {
    setDataCourse(state, action: PayloadAction<MypCourseSummaryT[]>) {
      state.memberCourseList = action.payload;
    },
    setDataBookMark(state, action: PayloadAction<MyBookMarkSummaryT[]>) {
      state.memberBookmarkedList = action.payload;
    },
  },
});

export const myInfoDataListReducer = myInfoDataListSlice.reducer;
export const myInfoDataListActions = myInfoDataListSlice.actions;

Redux Toolkit ์ž‘์„ฑํ•ด ์ฃผ๊ณ  ํƒ€์ž…๋„ ์ง€์ •ํ•ด ์ฃผ์—ˆ๋‹ค.
ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ์ธ์ž์— action์ด ๋“ค์–ด๊ฐˆ ๊ฒฝ์šฐ PayloadAction<ํƒ€์ž…>์„ ๊ผญ ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

useQuery({
    queryKey: ['mypage'],
    queryFn: () => GetMyList(),
    onSuccess: (data) => {
      dispatch(
        myInfoDataListActions.setDataCourse(
          data?.data.memberCourseList as MypCourseSummaryT[]
        )
      );
      dispatch(
        myInfoDataListActions.setDataBookMark(
          data?.data.memberBookmarkedList as MyBookMarkSummaryT[]
        )
      );
    },
  });

  const memberCourseList = useSelector(
    (state: RootState) => state.myInfoData.memberCourseList
  );
  const memberBookmarkedList = useSelector(
    (state: RootState) => state.myInfoData.memberBookmarkedList
  );

๊ทธ๋Ÿฌ๊ณ  useQuery๋ฅผ ๋ฐ”๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ 
API ํ˜ธ์ถœ์ด ์„ฑ๊ณต ํ–ˆ์„ ๋•Œ useDispatch๋ฅผ ์ด์šฉํ•ด ๊ฐ’์„ ํ• ๋‹นํ•ด ์ฃผ์—ˆ๊ณ 
useSelector๋ฅผ ์ด์šฉํ•ด ์ „์—ญ์œผ๋กœ ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

๊ทธ๋ ‡๊ฒŒ ํƒ€์ž…์ด ํ•ด๊ฒฐ ๋˜์—ˆ๋‚˜?


์•„๋‹ˆ๋‹ค... ์•„์ง๋„ ์˜ค๋ฅ˜๋Š” ํ•ด๊ฒฐ ๋˜์ง€ ์•Š์•˜๋‹ค.
๊ทธ๋ž˜๋„ ์–ด๋Š ์ •๋„ ์˜ค๋ฅ˜๋Š” ์ค„์–ด ๋“ค์—ˆ๋‹ค.

์ด๋Ÿฐ ์ž์ž˜ํ•œ ํƒ€์ž… ์˜ค๋ฅ˜๊ฐ€ ๋‚˜๋Š”๋ฐ ๊ฑฐ์ด ํ•ด๋‹น ๋ฐ์ดํ„ฐ์˜ ๋ฌธ์ œ ๋ณด๋‹จ
๋ฐ์ดํ„ฐ ์š”์ฒญ์ด๋‚˜ ๋ถ€๋ชจ ์š”์†Œ์˜ ์—๋Ÿฌ์ธ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๊ธฐ๋„ ํ•œ๋‹ค.

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ + eslint๋กœ ์ง„ํ–‰ํ•˜๋‹ค ๋ณด๋ฉด ์ž‘์–ด ์‹œ๊ฐ„ ๋ณด๋‹ค
ํƒ€์ž… ์—๋Ÿฌ ํ•ด๊ฒฐํ•˜๋Š” ์‹œ๊ฐ„์ด ๋” ์˜ค๋ž˜ ๊ฑฐ๋ฆด ๋•Œ๋„ ์žˆ๋Š”๊ฑฐ ๊ฐ™๋‹คใ… 

๊ทธ ๋งŒํผ ์ฝ”๋“œ๊ฐ€ ๊น”๋”ํ•ด ์ง€๊ณ  ๊ฐ€๋…์„ฑ์ด ์ข‹์•„์ง€๋Š” ์žฅ์ ๋„ ์žˆ๋Š” ๋“ฏ ์‹ถ๋‹ค.


โœ๏ธ ๋งˆ์น˜๋ฉฐ

๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ์ž‘์„ฑํ•œ ์ฝ”๋“œ ๋ถ„์„, ํƒ€์ž… ์—๋Ÿฌ๋กœ ์‹œ๊ฐ„์„ ๋งŽ์ด ๋‚ ๋ฆฐ ๋‚ ์ด๋‹ค...

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ, eslint๋Š” ์ด๋ฒˆ ๋ฉ”์ธ ํ”„๋กœ์ ํŠธ์—์„œ ์ฒ˜์Œ ์•Œ๊ฒŒ ๋œ ๋‚ด์šฉ์ด๋ผ...
ํƒ€์ž… ์—๋Ÿฌ๊ฐ€ ๋‹ค๋ฅธ ํŒ€์›๋“ค์— ๋น„ํ•ด ๋งŽ์•˜๊ณ  ํ•ด๊ฒฐํ•˜๋Š”๋ฐ ์˜ค๋žœ ์‹œ๊ฐ„์ด ๊ฑธ๋ ธ๋˜ ๊ฑฐ ๊ฐ™์•„ ์•„์‰ฌ์› ๋‹ค.

profile
๐Ÿ’ป ํ”„๋ก ํŠธ์—”๋“œ๋ฅผ ๋ชฉํ‘œ๋กœ ์„ฑ์žฅ ์ค‘! (์•Œ์•„๋ดค๋˜ ๋‚ด์šฉ ๋“ฑ์„ ์ •๋ฆฌํ•˜๊ธฐ)

0๊ฐœ์˜ ๋Œ“๊ธ€