본문 바로가기
프로젝트/2024

[react] 탭 메뉴 만들기

by dev__log 2024. 4. 16.

완성된 탭 메뉴

 

이번에 담당한 화면에 탭 메뉴가 필요한 부분이 2곳 정도 있어서, 컴포넌트로 만들어보기로 했다.

 

탭 메뉴 코드

TabProps에서 id는 탭 메뉴를 식별하고자 추가했고,

title은 탭 메뉴의 이름, content는 탭 메뉴를 눌렀을 때 나와야 하는 컴포넌트를 전달하고자 추가하였다.

 

탭 메뉴를 아래와 같이 배열로 전달하면 TabMenu.tsx 탭메뉴 컴포넌트에서 map으로 돌려서 렌더링 하게 된다.

const tabArr = [
    { id: 0, title: '내 프로필', content: <MyInfo /> },
    { id: 1, title: '내가 쓴 글', content: <WriteList /> },
    { id: 3, title: '좋아요 한 글', content: <LikeBoardList /> },
  ]

 

 

 

이렇게 위 탭 메뉴 정보 배열을 아래에 data에 담아서 props로 내려주게 된다.

여기서 width는 정말 고민되던 부분인데, 처음에는 width에 숫자만 내려주고 props 전달받은걸 탭메뉴 컴포넌트에서 w-1/${col} 이런 식으로 가변적으로 변경할 수 있게 만들려고 했으나, tailwind는 중간에 내용이 잘리게 되면 클래스가 인식을 못한다는 이슈가 있어서, width에 사용될 클래스를 아래와 같이 w-1/3처럼 완성해서 전달하기로 결정했다.

 

그래서 이렇게 가변적으로 width를 변경할 수 있게 했다. 3개의 사이즈가 동일한 탭 메뉴이므로 w-1/3 으로 주었고, 2개라면 w-1/2 이런 식으로 전달하면 된다.

<TabMenu data={tabArr} width='w-1/3' />

 

이렇게 전달된 width 는 탭메뉴의 클래스로 전달된다.

 

[ 전체 코드 ]

TabMenu.tsx

import React, { useState } from 'react'

type TabProps = {
  data: {
    id: number //탭 메뉴를 식별하고자 추가
    title: string //탭메뉴 타이틀
    content: React.JSX.Element //탭 메뉴에 눌렀을 때 나오는 컴포넌트
  }[]
  width: string //탭 메뉴 사이즈
}

const TabMenu = ({ data, width }: TabProps) => {
  const [isActive, setIsActive] = useState(0)

  const onClickTabHandler = (idx: number) => {
    setIsActive(idx)
  }

  const shadow = 'drop-shadow-[0px_1px_0px_#000000]'

  return (
    <div>
      <div
        className={`mb-8 mt-[2.75rem] flex border-b border-[#ffffff4d] ${shadow}`}
      >
        {data &&
          data.map((item, idx) => {
            return (
              <button
                key={item.id}
                type='button'
                onClick={() => onClickTabHandler(idx)}
                className={`${isActive === idx ? 'border-[#685BFF] text-[#685BFF]' : 'border-transparent text-[#ffffff80]'} mb-[-1px] p-[0.875rem] font-bold ${width}  border-b-2 text-[1.25rem] tracking-[-0.03em]`}
              >
                {item.title}
              </button>
            )
          })}
      </div>
      <div>{data[isActive].content}</div>
    </div>
  )
}

export default TabMenu

 

 

/mypage/page.tsx

'use client'

import LikeBoardList from '@/components/mypage/LikeBoardList'
import MyInfo from '@/components/mypage/MyInfo'
import TabMenu from '@/components/mypage/TabMenu'
import WriteList from '@/components/mypage/WriteList'

const MyPage = () => {
  const tabArr = [
    { id: 0, title: '내 프로필', content: <MyInfo /> },
    { id: 1, title: '내가 쓴 글', content: <WriteList /> },
    { id: 3, title: '좋아요 한 글', content: <LikeBoardList /> },
  ]

  return (
    <div>
      <TabMenu data={tabArr} width='w-1/3' />
    </div>
  )
}

export default MyPage

'프로젝트 > 2024' 카테고리의 다른 글

[react/nextjs] 양방향 무한스크롤 2  (0) 2024.04.26
최종 팀 프로젝트 Day9  (0) 2024.04.05
리액트로 슬라이드 만들기 2 + typescript  (0) 2024.04.04
최종 팀 프로젝트 Day8  (0) 2024.04.04
최종 팀 프로젝트 Day7  (1) 2024.04.04