Westagram ํšŒ๊ณ 

Seokhoยท2022๋…„ 6์›” 17์ผ
0

Westagram Project

๋ชฉ๋ก ๋ณด๊ธฐ
1/4

ํ”„๋กœ์ ํŠธ์˜ ์ด์œ  ๋ฐ ๋ชฉํ‘œ

ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋Š” ์ด์œ 

๋ถ€ํŠธ์บ ํ”„๋ฅผ ์กธ์—…ํ•˜๊ณ  ์ทจ์—…์ค€๋น„๋ฅผ ์‹œ์ž‘ํ•œ์ง€ ๋ฒŒ์จ 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)

๐ŸŒŸ Project Overview


โœ”๏ธ Github
โœ”๏ธ ํšŒ๊ณ 


์ž‘์—… ๊ธฐ๊ฐ„

22.06.05 - 22.06.16 (์‹ค์ œ ๊ฐœ๋ฐœ ๊ธฐ๊ฐ„ 7์ผ)

๊ธฐ์ˆ  ์Šคํƒ

JavaScript(ES6) | TypeScript | React | React Router | Styled-component | Axios

์ฃผ์š” ๊ตฌํ˜„์‚ฌํ•ญ

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ํ™œ์šฉ

  • TypeScript ๊ธฐ์ดˆ ํ•™์Šต ํ›„ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. (ํ•™์Šต ๊ธฐ๋ก ๋งํฌ)
  • Type์™€ Interface์˜ ๊ณตํ†ต์  ๋ฐ ์ฐจ์ด์ ์„ ํ•™์Šต ํ›„ Interface๋ฅผ ์ฃผ๋กœ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
  • Interface ๊ด€์‹ฌ์‚ฌ ๋ถ„๋ฆฌ๋ฅผ ํ†ตํ•ด ํšจ์œจ์ ์œผ๋กœ Type์„ ๊ด€๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.
// 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;
}

๋Œ“๊ธ€ ์ถ”๊ฐ€, ์‚ญ์ œ ๋ฐ ์ข‹์•„์š” ๊ธฐ๋Šฅ

  • ์ฒ˜์Œ ๋ Œ๋”๋ง๋˜๋Š” ๋Œ“๊ธ€ ๋ฆฌ์ŠคํŠธ์— ์ƒˆ๋กœ์šด id์˜ ๋Œ“๊ธ€์ด ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.
  • ๋Œ“๊ธ€์˜ ์ข‹์•„์š” ํ˜น์€ ์‚ญ์ œ ํด๋ฆญ ์‹œ id๊ฐ’์„ ํ™œ์šฉํ•ด ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.

Custom Hooks & Axios

  • ์ด์ „์— ์‚ฌ์šฉํ–ˆ๋˜ Fetch์™€ Axios์˜ ์ฐจ์ด์ ์„ ํ•™์Šต ํ›„ Axios๋ฅผ ํ™œ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
  • async / await๋ฅผ ์ด์šฉํ•ด ๋น„๋™๊ธฐ ํ†ต์‹ ์„ ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ํ”„๋กœ๊ทธ๋žจ ๋ฌธ์ œ ๋ฐœ์ƒ ์‹œ ๋Œ€์ฒ˜๋ฅผ ์œ„ํ•œ try / catch ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • Custom Hooks์„ ์‚ฌ์šฉํ•ด ๋กœ์ง์˜ ๋ฐ˜๋ณต์„ ์ตœ์†Œํ™”ํ•˜๊ณ  ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์˜€์Šต๋‹ˆ๋‹ค.
// 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;

๋ฐ˜์‘ํ˜• ๊ตฌํ˜„

  • ๊ฐ€๋ณ€ํ˜• ์ด๋ฏธ์ง€ ๋ฐ media query๋ฅผ ํ™œ์šฉํ•ด ๋ฐ˜์‘ํ˜• ์›น์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

์„ฑ๋Šฅ ์ตœ์ ํ™”

  • useCallback๊ณผ useMemo๋ฅผ ํ•™์Šต ํ›„ useCallback์„ ์‚ฌ์šฉํ•ด ์ตœ์ ํ™” ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.
// 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]
);

๊ตฌํ˜„ ๊ฒฐ๊ณผ

๋Œ“๊ธ€ ๊ฒŒ์‹œ๋ฌผ์„ ์ถ”๊ฐ€ ๋ฐ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋Œ“๊ธ€๊ณผ ๊ฒŒ์‹œ๋ฌผ์— ์ข‹์•„์š”๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜์‘ํ˜• ์›น์œผ๋กœ ๊ตฌํ˜„๋˜์–ด ๋‹ค์–‘ํ•œ ๋””๋ฐ”์ด์Šค ๋ฐ ๋ทฐํฌํŠธ์— ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐ŸŒŸ Project review

๊ณ ๋ฏผ๊ณผ ํ•ด๊ฒฐ(๋‚ด์šฉ ์ •๋ฆฌ ์ค‘)

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

  • ์Šคํƒ€์ผ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ ์‹œ ํƒ€์Šค
  • props ์ „๋‹ฌ ์‹œ ํƒ€์Šค

useCallback & useMemo

  • ์‚ฌ์šฉ ์ด์œ , ๋ฐฉ๋ฒ•, ์–ธ์ œ ์‚ฌ์šฉ?

axios์™€ customHook

  • axios์™€ fetch์˜ ์ฐจ์ด์ 
  • ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์‚ฌ์šฉ ์ด์œ , ์‚ฌ์šฉ ๋ฐฉ๋ฒ•
  • customHook ์‚ฌ์šฉ ์ด์œ , ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

์นญ์ฐฌํ•ด์ฃผ๊ณ  ์‹ถ์€ ์ 

โœ”๏ธ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ

์ƒˆ๋กœ์šด ๊ธฐ์ˆ ์„ ํ•™์Šตํ• ๋•Œ ๊ธฐ์ดˆ ํ•™์Šต ํ›„ ์ง์ ‘ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๋ฉฐ ์„ฑ๊ณต๊ณผ ์‹คํŒจ๋ฅผ ๊ฒฝํ—˜ํ•˜๋Š” ๊ฒƒ์€ ์„ฑ์žฅ์˜ ์ง€๋ฆ„๊ธธ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์ฒ˜์Œ์— ์–ด๋ ค์›€์„ ๋งŽ์ด ๋Š๊ผˆ๋Š”๋ฐ, ์ดˆ๊ธฐ ์„ธํŒ…๋ถ€ํ„ฐ ์ด์ „๊ณผ ๋‹ฌ๋ผ ํž˜๋“ค์—ˆ์œผ๋ฉฐ state์™€ ์ธ์ž ๋“ฑ ๋ชจ๋“  ๊ณณ์—์„œ ์˜ˆ์ƒํ•˜์ง€ ๋ชปํ•œ ์—๋Ÿฌ๊ฐ€ ๊ณ„์† ๋ฐœ์ƒํ•ด์„œ ์‰ฝ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
์ค‘๊ฐ„ ์ค‘๊ฐ„์— ํŽ˜์ด์ง€์™€ ๊ธฐ๋Šฅ๋ณ„๋กœ ๋ฆฌํŒฉํ† ๋ง์„ ํ•˜๋ฉฐ ์ง„ํ–‰ํ–ˆ๋Š”๋ฐ, props๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๋„ ์‰ฝ์ง€ ์•Š์•„ ๋ฆฌ์„œ์นญ์„ ํ†ตํ•ด ์—๋Ÿฌ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š”๋ฐ ์ „์ „๊ธ๊ธํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์–ด๋Š์ •๋„ ์ต์ˆ™ํ•ด์ง„ ํ›„๋กœ interface ๋ฅผ ๋ณด๋‹ค ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ตํž ์ˆ˜ ์žˆ์—ˆ๊ณ , ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ์— ๋Œ€ํ•ด์„œ ๋”์šฑ ์ž˜ ์•Œ๊ฒŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
์•„์ง ์™„๋ฒฝํ•˜์ง„ ์•Š์ง€๋งŒ, ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ํ†ตํ•ด์„œ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์™€ ์นœ์ˆ™ํ•ด์งˆ ์ˆ˜ ์žˆ์—ˆ๊ณ  ๊ณ„์† ๋ฆฌํŒฉํ† ๋ง ํ•˜๋ฉด์„œ ์•„์‰ฌ์šด ๋ถ€๋ถ„์„ ์ˆ˜์ • ๋ฐ ๋ณด์™„ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

โœ”๏ธ ์‹ค๋ ฅ ํ–ฅ์ƒ

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

์ด์œ ๋Š” ์ฒซ๋ฒˆ์งธ๋กœ, ์ƒ๊ฐ๋ณด๋‹ค ๋งŽ์€ ๊ณ ๋ฏผ์ด ํ•„์š”ํ•˜๋‹ค!
์ด์ „์— ์ž‘์„ฑํ–ˆ๋˜ ์ฝ”๋“œ๋“ค์„ ๋‹ค์‹œ ๋ถ„์„ํ•˜๋ฉด์„œ ํ‹€๋ ธ๋˜ ๋ถ€๋ถ„์€ ์ˆ˜์ •ํ•˜๊ณ  ๋ถ€์กฑํ–ˆ๋˜ ๋ถ€๋ถ„์€ ์ถ”๊ฐ€ํ–ˆ๋Š”๋ฐ, ์ด ๊ณผ์ •์—์„œ ์˜ˆ์ƒํ•˜์ง€ ๋ชปํ•œ ๊ณ ๋ฏผ๊ณผ ํ•™์Šต์ด ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค.

์™œ๋ƒํ•˜๋ฉด ์ด์ „์— ์ž˜๋ชป ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ฑฐ๋‚˜ ์ž˜๋ชป ์•Œ๊ณ  ์žˆ๋˜๊ฒƒ์„ ๋‹ค์‹œ ํ•™์Šตํ•ด์•ผ ํ–ˆ๊ณ , ๋น„ํšจ์œจ์ ์ธ ๋ถ€๋ถ„์„ ํšจ์œจ์ ์œผ๋กœ ์ˆ˜์ • ๋ณด์™„ํ•˜๋Š”๊ฒŒ ์ƒ๊ฐ๋ณด๋‹ค ์‰ฝ์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค.

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

๋‘๋ฒˆ์งธ, ์„ฑ์ทจ๊ฐ์„ ํ†ตํ•œ ์ž์กด๊ฐ, ์ž์‹ ๊ฐ ์ƒ์Šน!
์ €๋Š” ์†Œ์œ„ '์„ฑ์ทจ์ฃผ์˜์ž' ๋ผ๊ณ  ๋ถ€๋ฅผ๋งŒํผ ์„ฑ์ทจ๊ฐ์„ ํ†ตํ•ด ์‚ถ์˜ ํ™œ๋ ฅ์„ ๋Š๋ผ๋Š” ์‚ฌ๋žŒ์ด๊ณ , ์ปค๋ฆฌ์–ด ์ „ํ™˜์„ ํ•˜๊ฒŒ๋œ ์ด์œ  ์ค‘ ํ•˜๋‚˜์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

์ €์™€ ๊ฐ™์ด ํ•˜๋ฃจ ํ•˜๋ฃจ ์—ด์‹ฌํžˆ ๋…ธ๋ ฅํ•˜๋Š” ๊ตฌ์ง์ž๋“ค์€ ์ฒด๊ฐํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ถ„๋ช… ์‹ค๋ ฅ์ด ์กฐ๊ธˆ์”ฉ ๋Š˜๊ณ  ์žˆ์„ ๊ฒƒ ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ”ผ๋ถ€๋กœ ์™€๋‹ฟ์„ ์ •๋„๋กœ ๋Š๋ผ์ง€ ๋ชปํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์€๋ฐ, ์ €์—๊ฒŒ ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋Š” ์‹ค๋ ฅ ํ–ฅ์ƒ์„ ๋Š๋‚„ ์ˆ˜ ์žˆ๋Š” ๊ณ„๊ธฐ๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์ „์—๋Š” ์–ด๋–ป๊ฒŒ ์‹œ์ž‘ํ•ด์•ผํ• ์ง€ ๊ฐ๋„ ์•ˆ์™”๋˜ ๊ธฐ๋Šฅ์˜ ์ „์ฒด์ ์ธ ๋กœ์ง์˜ ํ๋ฆ„์„ ์–ด๋Š์ •๋„ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๊ณ , ๊ณ ๋ฏผ ์กฐ์ฐจ ํ•  ์ˆ˜ ์—†์—ˆ๋˜ ๊ธฐ๋Šฅ๊ณผ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•ด๋ณผ๊นŒ ๋ผ๋Š” ์ƒ๊ฐ๊นŒ์ง€ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
๊ฐœ์ธ์ ์œผ๋กœ ์ด ๋ถ€๋ถ„์—์„œ ๋‚˜๋ฆ„ ์„ฑ์žฅํ–ˆ๊ตฌ๋‚˜ ๋ผ๊ณ  ๋Š๊ผˆ๋Š”๋ฐ, ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ pagination ์€ ์ฒ˜์Œ๋ถ€ํ„ฐ ๊ณ ๋ คํ•˜์ง€ ์•Š๊ณ  ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ง‰๋ฐ”์ง€์— ์ฒ˜์Œ๋ถ€ํ„ฐ MainCard ๋ฅผ ๊ณตํ†ต์ปดํฌ๋„ŒํŠธ๋กœ ๋ฐ›์•„์˜ค๊ณ  MockData ๋ฅผ ํ™œ์šฉํ•ด Card ๋‚ด์šฉ์˜ api๋ฅผ ๋ฐ›์•„์™”์œผ๋ฉด pagination ์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์—ˆ๊ฒ ๋‹ค ๋ผ๋Š” ์ƒ๊ฐ์„ ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋”๋ถˆ์–ด search ๋ถ€๋ถ„์—์„œ ๊ฒ€์ƒ‰์„ ํ•˜๋ฉด Aside ์˜ ์ถ”์ฒœ์ธ๋“ค์„ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค๊ฑฐ๋‚˜, ์ข‹์•„์š” ๊ธฐ๋Šฅ์˜ Count ๋ฅผ ๋ณด์—ฌ์ค€๋‹ค๊ฑฐ๋‚˜ ๋“ฑ๋“ฑ ๋‹ค์–‘ํ•œ ์•„์ด๋””์–ด๋ฅผ ๊ณ ๋ฏผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์„ฑ์žฅ๊ณผ ๊ณ ๋ฏผ์„ ํ†ตํ•ด ๋„ˆ๋ฌด๋‚˜๋„ ํฐ ์„ฑ์ทจ๊ฐ์„ ๋Š๋ผ๊ฒŒ ๋˜์—ˆ๊ณ , ๋‹ค์‹œ ํ•œ๋ฒˆ ๊ฐœ๋ฐœ์— ์žฌ๋ฏธ์™€ ํฅ๋ฏธ๋ฅผ ๋Š๋‚„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ์ž ์„ ํƒํ•˜๊ธธ ์ž˜ํ–ˆ๋‹ค~ ๊ฟ€์žผ ๐Ÿ๐Ÿฏ

๊ฐœ์„ ํ•˜๊ณ  ์‹ถ์€ ์ 

โœ”๏ธ ๋ฆฌํŒฉํ† ๋ง

ํ”„๋กœ์ ํŠธ ๋ง‰๋ฐ”์ง€์— pagination ๊ตฌํ˜„์— ๋Œ€ํ•ด ๊ณ ๋ฏผํ–ˆ๋Š”๋ฐ, ์ดˆ๊ธฐ ์„ค๊ณ„๊ฐ€ pagination ๊ธฐ๋Šฅ์„ ๊ณ ๋ คํ•˜์ง€ ์•Š๊ณ  ์ง„ํ–‰ํ•ด์„œ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆด ๊ฒƒ์œผ๋กœ ํŒ๋‹จ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์ถ”ํ›„ ์ฒœ์ฒœํžˆ ์ง„ํ–‰ ์˜ˆ์ •์ด๊ณ , MockData ๋ฅผ ํ™œ์šฉํ•ด MainCard ์˜ userInfo ๋ฐ์ดํ„ฐ๋ฅผ api๋กœ ๋ฐ›์•„ ์ง„ํ–‰ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

โœ”๏ธ ์„ฑ๋Šฅ

์ตœ๊ทผ ๋ฉด์ ‘์—์„œ ๋งŽ์ด ์งˆ๋ฌธ์œผ๋กœ ๋‚˜์˜ค๋Š” ์„ฑ๋Šฅ ์ตœ์ ํ™” ๊ด€๋ จํ•ด์„œ ์ฐจ๊ทผ์ฐจ๊ทผ ํ•™์Šต ์ค‘์ž…๋‹ˆ๋‹ค.

์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ํฌ๊ฒŒ ๋‚˜๋ˆ„์–ด ๋ณด๋ฉด ๋กœ๋”ฉ ์ตœ์ ํ™”, ๋ Œ๋”๋ง ์ตœ์ ํ™”๋กœ ๋‚˜๋‰˜๋Š”๋ฐ, ๊ทธ์ค‘ ๋ฆฌ์•กํŠธ์—์„œ ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” useMemo์™€ useCallback์„ ํ•™์Šตํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด์ „๊นŒ์ง€ ๋ฉด์ ‘์šฉ์œผ๋กœ ํ•™์Šต๋งŒ ํ•ด๋ดค๊ณ  ์‹ค์ œ ์‚ฌ์šฉ ๊ฒฝํ—˜์„ ์ „๋ฌดํ–ˆ๋Š”๋ฐ, ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ ์ง์ ‘ ์‚ฌ์šฉํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ† ์ด ํ”„๋กœ์ ํŠธ๋ผ์„œ ํฐ ์ฒด๊ฐ์€ ๋ชปํ–ˆ์ง€๋งŒ, ์ด๋ฒˆ ๊ฒฝํ—˜์œผ๋กœ ์–ธ์ œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด ๊ณ ๋ฏผํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋กœ๋”ฉ ๋ฐ ๋ Œ๋”๋ง ์ตœ์ ํ™” ๊ด€๋ จ ๋ฐฉ๋ฒ•๊ณผ ๊ธฐ์ˆ ์ด ๋‹ค์–‘ํ•œ๋ฐ, ํ•˜๋‚˜์”ฉ ํ•™์Šตํ•˜๋ฉด์„œ ๋ฆฌํŒฉํ† ๋ง ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

profile
๊ฐ™์ด์˜ ๊ฐ€์น˜๋ฅผ ์†Œ์ค‘ํ•˜๊ฒŒ ์ƒ๊ฐํ•˜๋Š”, ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž ์ด์„ํ˜ธ ์ž…๋‹ˆ๋‹ค.

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