[React] Tab Component 구현하기

fejigu·2022년 8월 29일
12

Toy Project

목록 보기
3/6
post-thumbnail
post-custom-banner

👉🏻 Tab UI 컴포넌트는 동일한 메뉴 라인에서 뷰를 전환할 때 사용한다. 탭을 구현하면서, 탭들은 항상 동일한 면적을 차지하는 부분에 대해서 신경쓰며 진행했다. 다시 정리하며 복습하고자 한다.


💻 Tab 구현 결과

✔️ 클릭한 Tab 메뉴만 className(submenu focused)과 CSS 변경
✔️ TabMenu를 클릭하면 content의 내용 변경
✔️ TabMenu를 클릭하면 content의 내용 변경
✔️ transition 효과 넣어 자연스럽게 탭 변경


⭐️⭐️⭐️ 다시 확인할 부분

🔎 space-between : 본인은 탭들 사이의 간격을 동일하게 해서 탭들을 나누기 위해 space-between를 사용하였는데 .. ex) justify-content: space-between

🔎 calc() : 레퍼런스에서는 calc 함수를 이용하여 면적 100%를 3으로 나눠서 구현하였다. ex) width: calc(100% /3)

🔎.map() : map()메서드는 호출 배열의 모든 요소에 대해 제공된 함수를 호출한 결과로 채워진 새 배열을 만든다. map 함수는 계속해서 사용하고 있는데 사용할때마다 익숙하지 않아 MDN에 검색을 해보게 된다... map_MDN

array.map(callbackFunction(currenValue, index, array), thisArg)

💻 Tab 코드

import { useState } from 'react';
import styled from 'styled-components';

// Styled-Component 라이브러리를 활용해 TabMenu 와 Desc 컴포넌트의 CSS를 구현.

const TabMenu = styled.ul`
  background-color: #dcdcdc;
  color: rgb(232, 234, 237);
  font-weight: bold;
  display: flex;
  flex-direction: row;
  align-items: center;
  list-style: none;
  margin-bottom: 7rem;
  margin-top: 10px;

  .submenu {
  // 기본 Tabmenu 에 대한 CSS를 구현
    display: flex;
    /* justify-content: space-between;
    width: 380px;
    heigth: 30px; */
    width: calc(100% /3);
    padding: 10px;
    font-size: 15px;
    transition: 0.5s;
    border-radius: 10px 10px 0px 0px;
  }

  .focused {
   //선택된 Tabmenu 에만 적용되는 CSS를 구현
    background-color: rgb(255,255,255);
    color: rgb(21,20,20);
  }

  & div.desc {
    text-align: center;
  }
`;

const Desc = styled.div`
  text-align: center;
`;

export const Tab = () => {
  // Tab Menu 중 현재 어떤 Tab이 선택되어 있는지 확인하기 위한 currentTab 상태와 currentTab을 갱신하는 함수가 존재해야 하고, 초기값은 0.
  const [currentTab, clickTab] = useState(0);

  const menuArr = [
    { name: 'Tab1', content: 'Tab menu ONE' },
    { name: 'Tab2', content: 'Tab menu TWO' },
    { name: 'Tab3', content: 'Tab menu THREE' },
  ];

  const selectMenuHandler = (index) => {
    // parameter로 현재 선택한 인덱스 값을 전달해야 하며, 이벤트 객체(event)는 쓰지 않는다
    // 해당 함수가 실행되면 현재 선택된 Tab Menu 가 갱신.
    clickTab(index);
  };

  return (
    <>
      <div>
        <TabMenu>
          // 아래 하드코딩된 내용 대신에, map을 이용한 반복으로 코드를 수정
         // li 엘리먼트의 class명의 경우 선택된 tab 은 'submenu focused', 나머지 2개의 tab은 'submenu' 
          {/* <li className="submenu">{menuArr[0].name}</li>
          <li className="submenu">{menuArr[1].name}</li>
          <li className="submenu">{menuArr[2].name}</li> */}
          {menuArr.map((el,index) => (
              <li className={index === currentTab ? "submenu focused" : "submenu" }
              onClick={() => selectMenuHandler(index)}>{el.name}</li>
            ))}
        </TabMenu>
        <Desc>
          <p>{menuArr[currentTab].content}</p>
        </Desc>
      </div>
    </>
  );
};
profile
신규 서비스의 기획부터 개발, 운영까지 전 과정을 경험한 주니어 📱
post-custom-banner

0개의 댓글