๋ง์ดํ์ด์ง ๋ฆฌ์คํธ ์กฐํ ์์
์ ์งํํ๋ค.
์ผ์ , ์ฆ๊ฒจ์ฐพ๊ธฐ ํญ๋ฉ๋ด๊ฐ ์๊ณ
ํ๋จ์๋ ๋ณธ์ธ ์์ฑํ ์ผ์ , ์ฆ๊ฒจ์ฐพ๊ธฐํ ์นด๋๋ฅผ ๋ชจ์ ๋์๋ค.
๋ง์ดํ์ด์ง ๋ฆฌ์คํธ ์กฐํ๋ ๋คํํ ์ปค๋ฎค๋ํฐ ํ์ด์ง์ ๊ฑฐ์ ๋์ผํ๊ธฐ ๋๋ฌธ์
์กฐ๊ฑด์ด๋ props๋ง ์์ ํ๋ฉด ๋๋ค.
์ฌ๊ธฐ์ ๋ช๊ฐ์ง ์ด์ ์ฌํญ์ด ์์๋ค.
- ๋จ์ ์ฝ๋ ๊ณ ์น๋๊ฒ ๋ ํ๋ค๋ค...
- ํ์ ์คํฌ๋ฆฝํธ ํ์ , eslint ์๋ฌ ์ง์ง ๋ณต๋ณ์ด๋ค...ใ
์๋ ๋ง๋ค์ด์ ธ ์๋ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ๋๊ฒ ์ฌ์ธ ๊ฑฐ ๊ฐ์ง๋ง
์คํ๋ ค ๋ ํ๋ค๋ค.
๊ฐ๊ฐ ์ด๋ค ๊ธฐ๋ฅ์ ํ๊ณ ์๋์ง ํ์
ํด์ผ ํ๊ณ
์ด๋ค 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>
))}
๋คํํ ๋ฆฌ์คํธ ์กฐํํ๋ ๊ฑด ๊ธ๋ฐฉ ์ฒ๋ฆฌํ ์ ์์์ง๋ง,
์ฝ๋๋ฅผ ๋ถ์ํ๊ณ ์ดํดํ๋๋ฐ ๋ง์ ์๊ฐ์ด ํ์ ํ๊ณ
๋งํ ๋ ๋ง๋ค ์์
ํ์ ํ์ ๋ถ๊ป ์ฌ์ญค๋ด์ผ ํ์๋ค.
์ง์ง... ๊ธฐ๋ฅ ๊ตฌํ์ ์๋ฃ ํ๋๋ฐ
๋นจ๊ฐ์ค์ด ๋๋ฅผ ํ๋ค๊ฒ ํ๋ค.
๋ช ๊ฐ๋ ์ค๋ฐ๊ฟ ํด์ ๊ธ๋ฐฉ ํด๊ฒฐ ํ ์ ์์์ง๋ง
๊ฐํน ํด๋น ๊ฐ์ 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๋ ์ด๋ฒ ๋ฉ์ธ ํ๋ก์ ํธ์์ ์ฒ์ ์๊ฒ ๋ ๋ด์ฉ์ด๋ผ...
ํ์
์๋ฌ๊ฐ ๋ค๋ฅธ ํ์๋ค์ ๋นํด ๋ง์๊ณ ํด๊ฒฐํ๋๋ฐ ์ค๋ ์๊ฐ์ด ๊ฑธ๋ ธ๋ ๊ฑฐ ๊ฐ์ ์์ฌ์ ๋ค.