๋ถํธ์บ ํ๋ฅผ ์กธ์ ํ๊ณ ์ทจ์ ์ค๋น๋ฅผ ์์ํ์ง ๋ฒ์จ 4๊ฐ์์ฐจ๊ฐ ๋์์ต๋๋ค. 4๊ฐ์๋์ ๋ถ์กฑํ๋ CS ๋ฐ ๊ธฐ์ ๊ด๋ จ ํ์ต์ ๊พธ์คํ ํ๊ณ ์๊ณ , ๋ฉด์ ์ค๋น์ ์ด๋ ฅ์ ์ ๋ฆฌ ๋ฑ ๊ต์ฅํ ๋ง์ ๊ฒ๋ค์ ์ค๋นํ๊ณ ์์ต๋๋ค. ๋๋ถ์ด ์ง์๋ ๋ง์ด ํ๊ณ ๋ฉด์ ๋ ์๊ฐ๋ณด๋ค ๋ง์ด ๋ดค๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋๊ธฐ์ ๋ถํฐ ์ด์ ์์ํ๋ ์คํํธ์ ๊น์ง ๋๋ต 10๊ณณ ์ ๋ ๋ฉด์ ์ ์งํํ๋ฉด์ ๋ฉด์ ์คํฌ์ ๋ง์ด ์ตํ ์ ์์์ต๋๋ค.
ํ์ง๋ง ๋ฉด์ ์ ๋ณด๋ฉฐ ์์ฝ๊ฒ ๋๊ปด์ก๋ ๋ถ๋ถ์ด ์์ต๋๋ค. ์ทจ์ ์ ์ค๋นํ๋ฉฐ ์ต๊ทผ ํ์ฌ์์ ํ์๋ก ํ๋ ๋ค์ํ ์คํฌ๊ณผ ์ง์์ ํ์ตํด์๊ณ ๋ฉด์ ์๋ฆฌ์์ ์ด์ผ๊ธฐ๋ฅผ ํ์ง๋ง, ๊ฒฐ๊ณผ๋ฌผ๋ก ๋ณด์ฌ์ฃผ์ง ๋ชปํด ๊ธ์ ์ ์ธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ง ๋ชปํ๋ค๋ ์๊ฐ์ด ๋ง์ด ๋ค์์ต๋๋ค.
ํ์ง๋ง ๋ ์๋ก์ด ํ๋ก์ ํธ๋ฅผ ๊ธฐํ๋ถํฐ ๋์์ธ๊น์ง ์์ํ๊ธฐ์๋ ๋๋ฌด ๋ง์ ๋ฆฌ์์ค๊ฐ ํ์ํ๊ธฐ์ ๊ณ ๋ฏผํ๋ ์ค, ๋ถํธ์บ ํ์์ ์งํํ๋ Westagram ํ๋ก์ ํธ๋ฅผ ๋ฆฌํฉํ ๋ง ํ๋ฉด ์ข๊ฒ ๋ค๋ ์๊ฐ์ด ๋ค์์ต๋๋ค.
๊ทธ๋์ ์ต๊ทผ ํ์ ์ญ๋์ผ๋ก ์๊ผฝํ๋ ํ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ค์ฌ์ผ๋ก ํ๋ก์ ํธ๋ฅผ ์งํํ๊ณ , ์ด์ ์ ๊ตฌํํ์ง ๋ชปํ๋ ๊ธฐ๋ฅ์ ์ถ๊ฐ ๋ฐ ์์ ํ์ผ๋ฉฐ ์ฌ์ฉํด๋ณด์ง ์์๋ axios์ custom hook์ ์ฌ์ฉํด ํ๋ก์ ํธ๋ฅผ ์งํํ์ต๋๋ค.
TypeScript์ ์น์ํด์ง๋ ค๊ณ ๋ ธ๋ ฅํ์ผ๋ฉฐ, ์ด์ ํ๋ก์ ํธ์์ ๊ตฌํํ์ง ๋ชปํ๋ ๋๊ธ ์ถ๊ฐ, ์ญ์ ๋ฐ ์ข์์ ๊ธฐ๋ฅ์ ๊ตฌํํ์ต๋๋ค.
์ต๊ทผ๊น์ง ์ฌ์ฉํ๋ fetch๊ฐ ์๋ ํ์ ์์ ์ ํธํ๋ axios๋ฅผ ๊ฒฝํํ๊ณ , custom hook์ ์ฌ์ฉํด ๋ก์ง์ ๋ฐ๋ณต์ ์ต์ํํ๊ณ ์ฌ์ฌ์ฉ์ฑ์ ๋์์ต๋๋ค.
๊ด์ฌ์ ๊ฐ๊ณ ํ์ต ์ค์ธ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํด useCallback๊ณผ useMemo๋ฅผ ํ์ต ํ useCallback์ ์ค์ ๋ก ์ฌ์ฉํด ์ต์ ํ๋ฅผ ๊ตฌํํ์ต๋๋ค.
๋ํ, media query์ ๊ฐ๋ณํ ์ด๋ฏธ์ง๋ฅผ ํ์ฉํด ๋ฐ์ํ ์น์ ๊ตฌํํ์ต๋๋ค.
โ๏ธ TypeScript ํ์ฉ
โ๏ธ ๋๊ธ ์ถ๊ฐ, ์ญ์ ๋ฐ ์ข์์ ๊ธฐ๋ฅ
โ๏ธ Custom Hook & Axios ์ฌ์ฉ
โ๏ธ ๋ฐ์ํ ๊ตฌํ (Media Query ๋ฐ ๊ฐ๋ณํ ์ด๋ฏธ์ง)
โ๏ธ ์ฑ๋ฅ ์ต์ ํ (useCallback, useMemo)
22.06.05 - 22.06.16 (์ค์ ๊ฐ๋ฐ ๊ธฐ๊ฐ 7์ผ)
JavaScript(ES6) | TypeScript | React | React Router | Styled-component | Axios
// Interface.tsx
export interface ImageType {
id: number;
image: string;
description: string;
}
export interface CommentsType {
id: number;
name: string;
comments: string;
}
export interface IgetData {
url: string;
}
export interface IResponse {
id: number;
image: string;
name: string;
description: string;
}
// useAxios.tsx
import { useState, useEffect } from 'react';
import axios from 'axios';
import { IgetData, IResponse } from '../Type/Interface';
const useGetData = (url: IgetData) => {
const [data, setData] = useState<IResponse[]>();
const [isLoading, setIsLoading] = useState<boolean>(true);
const [error, setError] = useState<string>('');
useEffect(() => {
const fetchData = async () => {
try {
await axios(url)
.then(res => {
setData(res.data);
})
.finally(() => {
setIsLoading(false);
});
} catch (err: any) {
setError(err);
alert(err);
}
};
if (isLoading) {
fetchData();
}
}, [url]);
return { data, error, isLoading };
};
export default useGetData;
// MainCard.tsx
const addFeedComment = useCallback(() => {
if (!comment) return;
setCommentList([
...commentList,
{ id: ids, name: 'Seokho__lee', comments: comment },
]);
ids += 1;
setComment('');
}, [comment, setComment, commentList, setCommentList]);
const updateComment = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
setComment(e.target.value);
},
[setComment]
);
const keyEnter = useCallback(
(e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
addFeedComment();
}
},
[addFeedComment]
);
const removeComments = useCallback(
(id: number) => {
setCommentList(commentList.filter(comments => comments.id !== id));
},
[commentList]
);
๋๊ธ ๊ฒ์๋ฌผ์ ์ถ๊ฐ ๋ฐ ์ญ์ ํ ์ ์์ผ๋ฉฐ, ๋๊ธ๊ณผ ๊ฒ์๋ฌผ์ ์ข์์๋ฅผ ํ ์ ์์ต๋๋ค. ๋ฐ์ํ ์น์ผ๋ก ๊ตฌํ๋์ด ๋ค์ํ ๋๋ฐ์ด์ค ๋ฐ ๋ทฐํฌํธ์ ๋์ํ ์ ์์ต๋๋ค.
์๋ก์ด ๊ธฐ์ ์ ํ์ตํ ๋ ๊ธฐ์ด ํ์ต ํ ์ง์ ์ฝ๋๋ฅผ ์์ฑํด๋ณด๋ฉฐ ์ฑ๊ณต๊ณผ ์คํจ๋ฅผ ๊ฒฝํํ๋ ๊ฒ์ ์ฑ์ฅ์ ์ง๋ฆ๊ธธ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
ํ์ง๋ง ์ฒ์์ ์ด๋ ค์์ ๋ง์ด ๋๊ผ๋๋ฐ, ์ด๊ธฐ ์ธํ
๋ถํฐ ์ด์ ๊ณผ ๋ฌ๋ผ ํ๋ค์์ผ๋ฉฐ state์ ์ธ์ ๋ฑ ๋ชจ๋ ๊ณณ์์ ์์ํ์ง ๋ชปํ ์๋ฌ๊ฐ ๊ณ์ ๋ฐ์ํด์ ์ฝ์ง ์์์ต๋๋ค.
์ค๊ฐ ์ค๊ฐ์ ํ์ด์ง์ ๊ธฐ๋ฅ๋ณ๋ก ๋ฆฌํฉํ ๋ง์ ํ๋ฉฐ ์งํํ๋๋ฐ, props๋ฅผ ์ ๋ฌํ๋ ๊ฒ๋ ์ฝ์ง ์์ ๋ฆฌ์์นญ์ ํตํด ์๋ฌ๋ฅผ ํด๊ฒฐํ๋๋ฐ ์ ์ ๊ธ๊ธํ์ต๋๋ค. ํ์ง๋ง ์ด๋์ ๋ ์ต์ํด์ง ํ๋ก interface
๋ฅผ ๋ณด๋ค ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์ตํ ์ ์์๊ณ , ํ์
์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ๋ ์ด์ ์ ๋ํด์ ๋์ฑ ์ ์๊ฒ๋์์ต๋๋ค.
์์ง ์๋ฒฝํ์ง ์์ง๋ง, ์ด๋ฒ ํ๋ก์ ํธ๋ฅผ ํตํด์ ํ์
์คํฌ๋ฆฝํธ์ ์น์ํด์ง ์ ์์๊ณ ๊ณ์ ๋ฆฌํฉํ ๋ง ํ๋ฉด์ ์์ฌ์ด ๋ถ๋ถ์ ์์ ๋ฐ ๋ณด์ํ๋ ค๊ณ ํฉ๋๋ค.
๋์ ๊ฐ์ ๊ตฌ์ง์๋ค์ ์ฝ๋ฉ ํ ์คํธ, ์ด๋ ฅ์, ๋ฉด์ ๋ฑ ์ค๋นํด์ผํ ๊ฒ๋ค์ด ๋งค์ฐ ๋ง๊ธฐ ๋๋ฌธ์ ์๋ก์ด ํ๋ก์ ํธ๋ฅผ ์งํํ ์ง ๋ง์ง์ ๋ํ ์๊ฒฌ์ด ๋ค์ํฉ๋๋ค. ์ ๋ํ ๊ทธ๋ฌ๊ธฐ์ ํ์ง์๋ค์ ๋ฉํ ๋ง๊ณผ ์กฐ์ธ์ ๋ง์ด ๋ฐ์๋๋ฐ, ๋๋ถ๋ถ ์๋ก์ด ํ๋ก์ ํธ ๋ณด๋ค ์ด์ ํ๋ก์ ํธ๋ฅผ ๋ฆฌํฉํ ๋งํด์ ์ ๊ทธ๋ ์ด๋ํ๋ ๊ฒ์ด ๋ ์ค์ํ๋ค๋ ์๊ฒฌ์ด ๋๋ถ๋ถ์ด์์ต๋๋ค. ํ๋ก์ ํธ๋ฅผ ๋๋ ํ ์ ๋ ์ด ์๊ฒฌ์ ๋์ํ๊ฒ ๋์์ต๋๋ค.
์ด์ ๋ ์ฒซ๋ฒ์งธ๋ก, ์๊ฐ๋ณด๋ค ๋ง์ ๊ณ ๋ฏผ์ด ํ์ํ๋ค!
์ด์ ์ ์์ฑํ๋ ์ฝ๋๋ค์ ๋ค์ ๋ถ์ํ๋ฉด์ ํ๋ ธ๋ ๋ถ๋ถ์ ์์ ํ๊ณ ๋ถ์กฑํ๋ ๋ถ๋ถ์ ์ถ๊ฐํ๋๋ฐ, ์ด ๊ณผ์ ์์ ์์ํ์ง ๋ชปํ ๊ณ ๋ฏผ๊ณผ ํ์ต์ด ํ์ํ์ต๋๋ค.
์๋ํ๋ฉด ์ด์ ์ ์๋ชป ์ฌ์ฉํ๊ณ ์๊ฑฐ๋ ์๋ชป ์๊ณ ์๋๊ฒ์ ๋ค์ ํ์ตํด์ผ ํ๊ณ , ๋นํจ์จ์ ์ธ ๋ถ๋ถ์ ํจ์จ์ ์ผ๋ก ์์ ๋ณด์ํ๋๊ฒ ์๊ฐ๋ณด๋ค ์ฝ์ง๋ ์์์ต๋๋ค.
์๋ก์ด ํ๋ก์ ํธ๋ฅผ ์งํํ๋ ๊ฒ๋ ๋น์ฐํ ๋ง์ ๊ณ ๋ฏผ์ด ํ์ํ์ง๋ง, ์๊ฐ์ด ์์คํ ๊ตฌ์ง์ ์ ์ฅ์์๋ ์ด์ ํ๋ก์ ํธ๋ฅผ ๋ฆฌํฉํ ๋งํ๋๊ฒ ์๊ฐ ๋๋น ํจ์จ์ ์ธ ํ์ต ๋ฐฉ์์ด๋ผ๋ ์๊ฐ์ด ๋ค์์ต๋๋ค.
๋๋ฒ์งธ, ์ฑ์ทจ๊ฐ์ ํตํ ์์กด๊ฐ, ์์ ๊ฐ ์์น!
์ ๋ ์์ '์ฑ์ทจ์ฃผ์์' ๋ผ๊ณ ๋ถ๋ฅผ๋งํผ ์ฑ์ทจ๊ฐ์ ํตํด ์ถ์ ํ๋ ฅ์ ๋๋ผ๋ ์ฌ๋์ด๊ณ , ์ปค๋ฆฌ์ด ์ ํ์ ํ๊ฒ๋ ์ด์ ์ค ํ๋์ด๊ธฐ๋ ํฉ๋๋ค.
์ ์ ๊ฐ์ด ํ๋ฃจ ํ๋ฃจ ์ด์ฌํ ๋ ธ๋ ฅํ๋ ๊ตฌ์ง์๋ค์ ์ฒด๊ฐํ์ง ๋ชปํ ์ ์์ง๋ง, ๋ถ๋ช ์ค๋ ฅ์ด ์กฐ๊ธ์ฉ ๋๊ณ ์์ ๊ฒ ์ ๋๋ค. ํ์ง๋ง ํผ๋ถ๋ก ์๋ฟ์ ์ ๋๋ก ๋๋ผ์ง ๋ชปํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์๋ฐ, ์ ์๊ฒ ์ด๋ฒ ํ๋ก์ ํธ๋ ์ค๋ ฅ ํฅ์์ ๋๋ ์ ์๋ ๊ณ๊ธฐ๊ฐ ๋์์ต๋๋ค.
์์ ์๋ ์ด๋ป๊ฒ ์์ํด์ผํ ์ง ๊ฐ๋ ์์๋ ๊ธฐ๋ฅ์ ์ ์ฒด์ ์ธ ๋ก์ง์ ํ๋ฆ์ ์ด๋์ ๋ ํ์
ํ ์ ์๊ฒ ๋์๊ณ , ๊ณ ๋ฏผ ์กฐ์ฐจ ํ ์ ์์๋ ๊ธฐ๋ฅ๊ณผ ๊ธฐ์ ์ ์ฌ์ฉํด๋ณผ๊น ๋ผ๋ ์๊ฐ๊น์ง ํ ์ ์๊ฒ ๋์์ต๋๋ค.
๊ฐ์ธ์ ์ผ๋ก ์ด ๋ถ๋ถ์์ ๋๋ฆ ์ฑ์ฅํ๊ตฌ๋ ๋ผ๊ณ ๋๊ผ๋๋ฐ, ์ด๋ฒ ํ๋ก์ ํธ์์ pagination
์ ์ฒ์๋ถํฐ ๊ณ ๋ คํ์ง ์๊ณ ์์ํ์ต๋๋ค. ํ์ง๋ง ๋ง๋ฐ์ง์ ์ฒ์๋ถํฐ MainCard
๋ฅผ ๊ณตํต์ปดํฌ๋ํธ๋ก ๋ฐ์์ค๊ณ MockData
๋ฅผ ํ์ฉํด Card
๋ด์ฉ์ api๋ฅผ ๋ฐ์์์ผ๋ฉด pagination
์ ์ฝ๊ฒ ๊ตฌํํ ์ ์์๊ฒ ๋ค ๋ผ๋ ์๊ฐ์ ํ๊ฒ ๋์์ต๋๋ค. ๋๋ถ์ด search
๋ถ๋ถ์์ ๊ฒ์์ ํ๋ฉด Aside
์ ์ถ์ฒ์ธ๋ค์ ๊ฒ์ํ ์ ์๊ฒ ํ๋ค๊ฑฐ๋, ์ข์์ ๊ธฐ๋ฅ์ Count
๋ฅผ ๋ณด์ฌ์ค๋ค๊ฑฐ๋ ๋ฑ๋ฑ ๋ค์ํ ์์ด๋์ด๋ฅผ ๊ณ ๋ฏผํ ์ ์๊ฒ ๋์์ต๋๋ค.
์ด๋ฌํ ์ฑ์ฅ๊ณผ ๊ณ ๋ฏผ์ ํตํด ๋๋ฌด๋๋ ํฐ ์ฑ์ทจ๊ฐ์ ๋๋ผ๊ฒ ๋์๊ณ , ๋ค์ ํ๋ฒ ๊ฐ๋ฐ์ ์ฌ๋ฏธ์ ํฅ๋ฏธ๋ฅผ ๋๋ ์ ์์์ต๋๋ค.
๊ฐ๋ฐ์ ์ ํํ๊ธธ ์ํ๋ค~ ๊ฟ์ผ ๐๐ฏ
ํ๋ก์ ํธ ๋ง๋ฐ์ง์ pagination
๊ตฌํ์ ๋ํด ๊ณ ๋ฏผํ๋๋ฐ, ์ด๊ธฐ ์ค๊ณ๊ฐ pagination
๊ธฐ๋ฅ์ ๊ณ ๋ คํ์ง ์๊ณ ์งํํด์ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆด ๊ฒ์ผ๋ก ํ๋จ๋์์ต๋๋ค.
๊ทธ๋์ ์ถํ ์ฒ์ฒํ ์งํ ์์ ์ด๊ณ , MockData
๋ฅผ ํ์ฉํด MainCard
์ userInfo
๋ฐ์ดํฐ๋ฅผ api๋ก ๋ฐ์ ์งํ ์์ ์
๋๋ค.
์ต๊ทผ ๋ฉด์ ์์ ๋ง์ด ์ง๋ฌธ์ผ๋ก ๋์ค๋ ์ฑ๋ฅ ์ต์ ํ ๊ด๋ จํด์ ์ฐจ๊ทผ์ฐจ๊ทผ ํ์ต ์ค์ ๋๋ค.
์ฑ๋ฅ ์ต์ ํ๋ฅผ ํฌ๊ฒ ๋๋์ด ๋ณด๋ฉด ๋ก๋ฉ ์ต์ ํ, ๋ ๋๋ง ์ต์ ํ๋ก ๋๋๋๋ฐ, ๊ทธ์ค ๋ฆฌ์กํธ์์ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ๊ตฌํํ ์ ์๋ useMemo
์ useCallback
์ ํ์ตํ์ต๋๋ค.
์ด์ ๊น์ง ๋ฉด์ ์ฉ์ผ๋ก ํ์ต๋ง ํด๋ดค๊ณ ์ค์ ์ฌ์ฉ ๊ฒฝํ์ ์ ๋ฌดํ๋๋ฐ, ์ด๋ฒ ํ๋ก์ ํธ์์ ์ง์ ์ฌ์ฉํด๋ณด์์ต๋๋ค. ํ์ง๋ง ํ ์ด ํ๋ก์ ํธ๋ผ์ ํฐ ์ฒด๊ฐ์ ๋ชปํ์ง๋ง, ์ด๋ฒ ๊ฒฝํ์ผ๋ก ์ธ์ ์ฌ์ฉํด์ผ ํ๋์ง์ ๋ํด ๊ณ ๋ฏผํ ์ ์์์ต๋๋ค.
๋ก๋ฉ ๋ฐ ๋ ๋๋ง ์ต์ ํ ๊ด๋ จ ๋ฐฉ๋ฒ๊ณผ ๊ธฐ์ ์ด ๋ค์ํ๋ฐ, ํ๋์ฉ ํ์ตํ๋ฉด์ ๋ฆฌํฉํ ๋ง ์์ ์ ๋๋ค.