2022/01/11

devPomme·2022년 1월 11일
0

21REBIRTH

목록 보기
4/10

오늘 한 것

  1. 내 정보 페이지 메뉴 레이아웃팅
  2. 로그인 기록 페이지
  3. 내가 쓴 글 내역 페이지
  4. 회원 탈퇴 페이지

공통 레이아웃에서 탭메뉴 코드 리팩토링하기

선택된 탭과 페이지네이션 넘버를 쿼리값으로 받아서 탭 또는 페이지네이션 넘버가 바뀔 때마다 페이지 라우팅을 한다.

import { Fragment, useState, useCallback } from 'react';
import Image from 'next/image';
import { useRouter } from 'next/router';
import Footer from 'src/components/Common/Footer';

function UserBoardLog(props: any) {
  const router = useRouter();
  const { type } = props;
  const { tab, page } = router.query;
  
  const tabList = [
    { id: 'post', name: '내가 쓴 글' },
    { id: 'comment', name: '내가 쓴 댓글' },
    { id: 'like', name: '좋아요 한 글' },
  ];
  
  const changeTab = useCallback(
    (tab: string) => {
      router.push({
        pathname: '',
        query: {
          tab,
        },
      });
    },
    [tab],
  );

  const TabItem = (props) => {
    const { key, onClick, active, name } = props;
    return (
      <div onClick={onClick} key={key} className={active ? 'active' : ''}>
        {name}
      </div>
    );
  };
  return (
    <>
      <Fragment>
        <div className="main-container" >
          <div className="board-log container">
            <div className="header">
              <div className="back" onClick={(e) => router.back()}>
                <Image src="/svg/LeftArrow.svg" width={22} height={19} />
              </div>
              <div className="title">내가 쓴 글</div>
            </div>
            <div className="tab">
              {tabList.map((item, index) => (
                <TabItem
                  key={index}
                  onClick={() => changeTab(item.id)}
                  active={item.id === tab}
                  name={item.name}
                />
              ))}
            </div>
            /* props.children 에 자식 컴포넌트들이 들어간다. */
            <div className="body">{props.children}</div>
          </div>
          <Footer />
        </div>
      </Fragment>
    </>
  );
}

export default UserBoardLog;

생성한 레이아웃은 자식 컴포넌트의 layout속성으로 선언해주면 끝!

/* pages/my/board.tsx */

import Image from 'next/image';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import UserBoardLog from 'src/layouts/myboard';
import Pagination from 'src/components/Common/Pagination';
import Footer from 'src/components/Common/Footer';

const dummyPostData = [
  {
    title: '업비트 아하토큰 245개 에어드랍',
    category: 'free',
    publishTimestamp: '2021-06-11',
    commentCount: 7,
  },
  {
    title: '업비트 아하토큰 245개 에어드랍',
    category: 'free',
    publishTimestamp: '2021-06-11',
    commentCount: 7,
  },
];
const MyBoard = () => {
  const router = useRouter();
  const { tab, page } = router.query;
  const [currentPage, setCurrentPage] = useState(1);
  const [postPerPage] = useState(20);

  const [Posts, setPosts] = useState<any[]>(dummyPostData);

  const onChangePage = (page: number) => {
    setCurrentPage(page);
    router.replace(
      {
        query: {
          tab,
          page: page,
        },
      },
      undefined,
      {
        shallow: false,
      },
    );
  };

  useEffect(() => {
    // TODO: tab 또는 page가 바뀔 때마다 data fetch, setPosts 실행
    window.scrollTo(0, 0);
  }, [tab, page]);
  
  const RenderedList = (query: any) => {
    return Posts.map((el, index) => {
      // 생략
    }
  };

  return (
   /* 게시물 리스트가 표시되는 영역으로, UserBoardLog 레이아웃 컴포넌트의 props.children 으로 들어간다. */                  
    <>
      <div className="list">{RenderedList(tab)}</div>
      <Pagination
        postPerPage={postPerPage}
        totalPosts={Posts.length}
        paginate={onChangePage}
        currentPage={currentPage}
      />
    </>
  );
};

MyBoard.layout = UserBoardLog;
export default MyBoard;

사실 레이아웃 컴포넌트를 사용하려면, 미리 _app.tsx에서 <Layout>컴포넌트에 대한 선언을 해주어야한다. 이 부분은... 내가 좀 더 잘 설명할 수 있을 만큼 정확히 이해를 했을 때 글을 써봐야겠다.

profile
헌신하고 확장하는 삶

0개의 댓글