✨ 기억보다 기록을/프로젝트

20241122(금) ▶️ 굿즈샵 상세보기 페이지 - 버튼 클릭 시 해당 탭 메뉴 내용 보여주기

서카츄 2024. 11. 22. 11:48

상세보기 페이지에 있는 탭 메뉴를 구현해 보려고 한다.

탭 메뉴는 `상세보기`와 `리뷰` 탭 이렇게 두개가 있는데, 해당 버튼을 클릭하면 해당 내용이 보이도록 조건부 랜더링을 작성해 보았다.

 

 

 

 

 

//ProductDescription.tsx

const ProductDescription = ({ id }: ShopMenuProps) => {
  const [activeTab, setActiveTab] = useState<"description" | "review">(
    "description"
  );

  return (
    <div className="py-28 w-full">
      <TabMenu id={id} activeTab={activeTab} setActiveTab={setActiveTab} />
      {activeTab === "description" ? (
        <DescriptionTab id={id} />
      ) : (
        <ReviewTab id={id} />
      )}
    </div>
  );
};

export default ProductDescription;

 

상세보기 탭 메뉴를 보여주는 부모 컴포넌트이다.

자식 컴포넌트에게 id를 props으로 넘겨주고, 탭 메뉴는 state 값을 넘겨준다.

 

 

 

 

 

 

const [activeTab, setActiveTab] = useState<"description" | "review">(
  "description"
);

 

useState를 사용해서 `description` 과 `review` 를 넣고, 초기값은 상세보기 페이지를 보여줘야하니 description 을 넣어주었다.

activeTab에서는 유니온 타입을 넣어줘서 명시적으로 2가지 타입만 들어올 수 있도록 만들었다.

 

 

 

 

 

 

{activeTab === "description" ? (
    <DescriptionTab id={id} />
  ) : (
    <ReviewTab id={id} />
)}

 

그리고 조건에 따라 해당 페이지가 `description` 이면 상세보기 페이지를,

아니면 리뷰 탭 페이지를 보여준다.

 

 

 

 

 

 

//TabMenu.tsx

const TabMenu = ({ activeTab, setActiveTab, id }: TabMenuProps) => {
  const { data } = useShop(id);

  return (
    <div className="mb-16">
      <ul className="flex justify-between items-center text-center cursor-pointer">
        <li
          onClick={() => setActiveTab("description")}
          className={`${
            activeTab === "description"
              ? "border-b-2 border-dark-gray"
              : "border-b"
          } w-2/4 py-4`}
        >
          <h3 className={`${activeTab === "description" ? "font-bold" : ""}`}>
            상세정보
          </h3>
        </li>
        <li
          onClick={() => setActiveTab("review")}
          className={`${
            activeTab === "review" ? "border-b-2 border-dark-gray" : "border-b"
          } w-2/4 py-4`}
        >
          <h3
            className={`${
              activeTab === "review" ? "font-bold" : ""
            } flex gap-2 justify-center items-center`}
          >
            리뷰<span>{data?.review_count}</span>
          </h3>
        </li>
      </ul>
    </div>
  );
};

export default TabMenu;

 

탭 메뉴 컴포넌트 코드는 이렇게 구성되어 있다.

 

 

 

 

 

 

 

  <li
    onClick={() => setActiveTab("description")}
    className={`${
      activeTab === "description"
        ? "border-b-2 border-dark-gray"
        : "border-b"
    } w-2/4 py-4`}
  >
    <h3 className={`${activeTab === "description" ? "font-bold" : ""}`}>
      상세정보
    </h3>
  </li>

 

상세정보와 리뷰 탭 같은 경우 조건부로 `setActiveTab`이 `description`일때 스타일을 추가해준다.

 

 

 

 

 

 

 

 

<li
    onClick={() => setActiveTab("review")}
    className={`${
      activeTab === "review" ? "border-b-2 border-dark-gray" : "border-b"
    } w-2/4 py-4`}
  >
    <h3
      className={`${
        activeTab === "review" ? "font-bold" : ""
      } flex gap-2 justify-center items-center`}
    >
      리뷰<span>{data?.review_count}</span>
    </h3>
  </li>

 

리뷰 탭 같은 경우에도 같이 조건부 랜더링을 적용해준다.

 

 

 

 

 

 

결과