โœ๐Ÿป [Code Camp_TIL] 14์ผ์ฐจ

code_Jยท2023๋…„ 4์›” 4์ผ
0

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
20/41
post-thumbnail

ํŽ˜์ด์ง€๋„ค์ด์…˜


ํŽ˜์ด์ง€๋„ค์ด์…˜์€ ํŽ˜์ด์ง€ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ, ๋‹ค์Œ ํŽ˜์ด์ง€๋กœ ๋„˜์–ด๊ฐ€๋Š” ๊ฒƒ์„ ๋œปํ•œ๋‹ค. ํฌ๊ฒŒ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ์‹๊ณผ, ๋ฌดํ•œ์Šคํฌ๋กค ๋ฐฉ์‹์ด ์žˆ๋‹ค.

๊ธฐ๋ณธ์ ์ธ ๋ฐฉ์‹์€ ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ๋ฅผ ํด๋ฆญํ•ด์„œ ์ด๋™ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ๊ฒŒ์‹œํŒ ํ˜•ํƒœ์˜ ํŽ˜์ด์ง€์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ๋ฐฉ์‹์ด๋‹ค.


๋ฌดํ•œ์Šคํฌ๋กค ๋ฐฉ์‹์€ ์ธ์Šคํƒ€๊ทธ๋žจ, ํŽ˜์ด์Šค๋ถ ๋“ฑ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ๊ฒŒ์‹œ๊ธ€ ์•„๋ž˜์ชฝ์œผ๋กœ ์Šคํฌ๋กค์„ ๋‚ด๋ฆฌ๋ฉด ๊ณ„์†ํ•ด์„œ ์ƒˆ๋กœ์šด ๊ฒŒ์‹œ๊ธ€์ด ๋‚˜์˜จ๋‹ค.


์˜ค๋Š˜์€ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ์‹์„ ์‹ค์Šตํ•ด๋ณด์•˜๋‹ค.

  1. ๋จผ์ € ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก์„ ์กฐํšŒํ•˜๋Š” API์™€ ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ์ „์ฒด ๊ฐฏ์ˆ˜ API๋ฅผ ๊ฐ€์ ธ์™”๋‹ค.
// pagination ๊ตฌํ˜„ ์œ„ํ•ด page๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„์˜ด!
const FETCH_BOARDS = gql`
  query fetchBoards($page: Int) {
    fetchBoards(page: $page) {
      _id
      writer
      title
      contents
    }
  }
`;

// ๊ฒŒ์‹œ๊ธ€ ์ „์ฒด ๊ฐฏ์ˆ˜
const FETCH_BOARDS_COUNT = gql`
  query {
    fetchBoardsCount
  }
`;

  1. ๊ฐ ํŽ˜์ด์ง€์˜ ์‹œ์ž‘ ํŽ˜์ด์ง€(1, 11, 21, 31...)์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด startPage๋ผ๋Š” state๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๊ณ , ์ดˆ๊ธฐ๊ฐ’์„ 1๋กœ ์ •ํ–ˆ๋‹ค.
export default function StaticRoutingPage(): JSX.Element {
  const [startPage, setStartPage] = useState(1); 

  1. 2ํŽ˜์ด๋กœ ๋„˜์–ด๊ฐ”์„ ๋•Œ ๋‹ค์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์™€์•ผ ํ•˜๋ฏ€๋กœ refetch๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. fetchBoardsCount์—์„œ๋„ data๋ฅผ ๋ฐ›์•„์˜ค๋„๋ก ์„ค์ •ํ•œ๋‹ค.
  const { data, refetch } = useQuery(FETCH_BOARDS);

  // data ์ค‘๋ณต๋˜๋ฏ€๋กœ ์ด๋ฆ„ ๋ฐ”๊ฟ”์ฃผ๊ธฐ
  const { data: dataBoardCount } = useQuery(FETCH_BOARDS_COUNT);

  1. fetchBoardsCount์—์„œ ์ „์ฒด ๊ฒŒ์‹œ๊ธ€ ์ˆ˜๋ฅผ ๋ถˆ๋Ÿฌ์™€์„œ 10์œผ๋กœ ๋‚˜๋ˆ ์ฃผ๋ฉด ํ•œ ํŽ˜์ด์ง€์— 10๊ฐœ์”ฉ ๋ณด์ด๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ, fetchBoardsCount๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์—๋„ ํ•œ ํŽ˜์ด์ง€๋Š” ๋ณด์ด๊ฒŒ ํ•ด์ค€๋‹ค.
  const lastPage = Math.ceil((dataBoardCount?.fetchBoardsCount ?? 10) / 10); 

  1. onClickPage, onClickPrevPage, onClickNextPage ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.
  const onClickPage = (event): void => {
    void refetch({
      page: Number(event.currentTarget.id),
      // id๋Š” ๋ฌธ์ž์—ด๋กœ ๋ฐ›์•„์˜ค๊ธฐ ๋•Œ๋ฌธ์— ์ˆซ์ž๋กœ ๋ณ€๊ฒฝํ•ด์ค˜์•ผ ํ•จ.
    });
  };
  
  const onClickPrevPage = (): void => {
    if (startPage === 1) return;
    setStartPage(startPage - 10);
    void refetch({ page: startPage - 10 });
  };

  const onClickNextPage = (): void => {
    if (startPage + 10 <= lastPage) {
      // ๋งˆ์ง€๋ง‰ ํŽ˜์ด์ง€ = (๊ฒŒ์‹œ๊ธ€ ๊ฐฏ์ˆ˜ / 10) ํ•œ ๊ฒƒ์„ ์˜ฌ๋ฆผ
      setStartPage(startPage + 10);
      void refetch({ page: startPage + 10 }); 
      // 11ํŽ˜์ด์ง€๋กœ ๋„˜์–ด๊ฐ”์„ ๋•Œ 11ํŽ˜์ด์ง€๋ถ€ํ„ฐ ์ญ‰ ๊ทธ๋ ค์ฃผ๋„๋ก ํ•จ.
    }
  };

  1. map์„ ํ™œ์šฉํ•ด์„œ ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก์˜ ์ œ๋ชฉ(title)๊ณผ ์ž‘์„ฑ์ž(writer)์„ ๊ฐ€์ ธ์˜ค๊ณ , ์›์†Œ๊ฐ€ 10๊ฐœ์งœ๋ฆฌ์ธ ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด์„œ ๋ชฉ๋ก์„ ๋ฐฐ์น˜ํ•ด์ค€๋‹ค.
  return (
    <div>
      {data?.fetchBoards.map((el) => (
        <div key={el._id}>
          <span style={{ margin: "10px" }}>{el.title}</span>
          <span style={{ margin: "10px" }}>{el.writer}</span>
        </div>
      ))}
      <span onClick={onClickPrevPage}>์ด์ „ํŽ˜์ด์ง€</span>
      {new Array(10).fill("์ฒ ์ˆ˜").map(
        (_, index) =>
          // ์–ธ๋”๋ฐ”(_)๋Š” ์ž„์‹œ๊ฐ’
          index + startPage <= lastPage && (
            <span
              key={index + startPage}
              id={String(index + startPage)}
              onClick={onClickPage}
            >
              {index + startPage}
            </span>
          )
      )}
      <span onClick={onClickNextPage}>๋‹ค์ŒํŽ˜์ด์ง€</span>
    </div>
  );
}


profile
Web FE ๊ฐœ๋ฐœ์ž ์ทจ์ค€์ƒ

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