[Recycle] Tab 컴포넌트 재사용하기

Heera1·2023년 1월 3일
0

Recycle

목록 보기
1/1

Tab 컴포넌트 재사용하기

  • 부모 컴포넌트에서 .map() 을 사용하지 않고 자식 컴포넌트에서 사용할 경우

컴포넌트 props로 배열 보내기

  • Tab 컴포넌트를 재사용하기 위해 TabARR.tsx 파일에 탭 메뉴들을 배열로 만들어줌
export const BlogMenus = [
  { id: 0, name: "블로그", content: "Tab menu 블로그" },
  { id: 1, name: "판매", content: "Tab menu 판매" },
  { id: 2, name: "댓글", content: "Tab menu 댓글" },
  { id: 3, name: "좋아요", content: "Tab menu 좋아요" },
];

export const SaleMenus = [
  { id: 4, name: "내 정보 관리", content: "Tab 내정보 관리" },
  { id: 5, name: "판매 작품", content: "Tab 판매 작품" },
  { id: 6, name: "구매 작품", content: "Tab 구매 작품" },
  { id: 7, name: "판매 관리", content: "Tab 판매 관리" },
];

  • 부모 컴포넌트에서 자식 컴포넌트로 배열들을 props로 내려보냄
// ../pages/blog
import { BlogMenus } from "../src/components/Tab/TabArr";
return(
	// .. 생략
	<BlogContent>
 	 <BlogTab Menus={BlogMenus} />
	</BlogContent>
  )

// ../pags/mypage
import { SaleMenus } from "../src/components/Tab/TabArr";
return(
	// .. 생략
  <MypageTitle>
	<BlogTab Menus={SaleMenus} />
  </MypageTitle>
 )

  • 자식 컴포넌트에서 props로 받고 interface 설정
  • .map() 메소드를 사용해 Tab 메뉴들을 만들어줌
  • Tab 클릭할 때마다 다른 컴포넌트가 나오게 함
interface TabProps {
  Menus: {
    id: number;
    name: string;
    content: string;
  }[];
}

export default function Tab({ Menus }: TabProps) {
  // 어떤 Tab이 선택되어 있는지 확인하기 위한
  const [curIndex, setIndex] = useState(0);
  const onClickMenuHandler = (index: number) => {
    setIndex(index);
  };
  
  return(
        <>
      <TabMenu>
        {Menus.map((section, index: number) => (
          <li
            role="presentation"
            key={index}
            className={
              curIndex === index ? "tab-submenu tab-focused" : "tab-submenu"
            }
            onClick={() => onClickMenuHandler(index)}
          >
            {section.name}
          </li>
        ))}
      </TabMenu>
      <TabContent>
        {Menus[curIndex].name === "블로그" ? <BlogList /> : null}
        {Menus[curIndex].name === "판매" ? <SaleList /> : null}
        {Menus[curIndex].name === "댓글" ? <MyCommentList /> : null}
        {Menus[curIndex].name === "좋아요" ? <LikeList /> : null}
        {Menus[curIndex].name === "내 정보 관리" ? <ProductstList /> : null}
        {Menus[curIndex].name === "판매 작품" ? <ProductstList /> : null}
        {Menus[curIndex].name === "구매 작품" ? <ProductstList /> : null}
        {Menus[curIndex].name === "판매 관리" ? <ProductstList /> : null}
      </TabContent>
    </>
  )
}

어려웠던 점

처음엔 name이 아니라 idx로 작성했었는데 idx의 경우 어떤 식으로 자동 생성되는 지 모르겠어서 한 눈에 알아볼 수 있는 name으로 변경하였다.

props의 type을 정하는 방법이 생각보다 잘 되지 않아서 어려웠다.

interface TabProps {
  id: number;
  name: string;
  content: string;
}

export default function Tab({ Menus }: TabProps) {
//생략
  <TabMenu>
        {Menus.map((section, index: number) => (
          <li
            role="presentation"
            key={index}
            className={
              curIndex === index ? "tab-submenu tab-focused" : "tab-submenu"
            }
            onClick={() => onClickMenuHandler(index)}
          >
            {section.name}
          </li>
        ))}
      </TabMenu>
  //생략
}

'id' PropType is defined but prop is never used
'content' PropType is defined but prop is never used
'TabProps' 형식에 'Menus' 속성이 없습니다.ts(2339)
'section' 매개 변수에는 암시적으로 'any' 형식이 포함됩니다.ts(7006)

  • TabProps 형식에 Menus 속성이 없습니다를 해결하기 위해 인터페이스에 Menus 를 배열로 넣어줬다.
interface TabProps {
  Menus: [id: number, name: string, content: string];
}

export default function Tab({ Menus }: TabProps) {
	//생략
      <TabMenu>
        {Menus.map((section, index: number) => (
          <li
            role="presentation"
            key={index}
            className={
              curIndex === index ? "tab-submenu tab-focused" : "tab-submenu"
            }
            onClick={() => onClickMenuHandler(index)}
          >
            {section.name}
          </li>
        ))}
      </TabMenu>
      <TabContent>
        {Menus[curIndex].name === "블로그" ? <BlogList /> : null}
        {Menus[curIndex].name === "판매" ? <SaleList /> : null}
        {Menus[curIndex].name === "댓글" ? <MyCommentList /> : null}
        {Menus[curIndex].name === "좋아요" ? <LikeList /> : null}
        {Menus[curIndex].name === "내 정보 관리" ? <ProductstList /> : null}
        {Menus[curIndex].name === "판매 작품" ? <ProductstList /> : null}
        {Menus[curIndex].name === "구매 작품" ? <ProductstList /> : null}
        {Menus[curIndex].name === "판매 관리" ? <ProductstList /> : null}
      </TabContent>
    </>

'string | number' 형식에 'name' 속성이 없습니다. 'string' 형식에 'name' 속성이 없습니다.ts(2339)

  • string | number 형식에 name 속성이 없다고? TabArr를 다시 한 번 살펴봤다. 배열 안에 객체로 들어가 있는 형태이다. 아, 그럼 인터페이스도 배열 안에 객체로 수정해주면 되겠다!
interface TabProps {
  Menus: {
    id: number;
    name: string;
    content: string;
  }[];
}
profile
웹 개발자

0개의 댓글