프론트/리액트

반복되는 JSX 문법 .map으로 간략하게

뽀짝코딩 2025. 6. 10. 21:17
728x90

로그인시 로그인 종류를 몇가지 만들었다. 탭선택에 따라 form이 다르게 나온다.

 

중복된 코드

      <ul className="flex flex-row gap-2 text-center px-4">
        <li className="px-2" onClick={() => setActiveTab("email")}>
          <div className={hover:text-[#0073e9] ${activeTab === "email" ? "text-[#0073e9]" : ""}}>
            이메일 로그인
          </div>
          {activeTab === "email" && <div className="border-b border-blue-600 pb-2 "></div>}
        </li>
        <li className="px-2" onClick={() => setActiveTab("qr")}>
          <div className={hover:text-[#0073e9] ${activeTab === "qr" ? "text-[#0073e9]" : ""}}>
            QR코드 로그인
          </div>
          {activeTab === "qr" && <div className="border-b border-blue-600 pb-2 "></div>}
        </li>
        <li className="px-2" onClick={() => setActiveTab("nonMember")}>
          <div
            className={hover:text-[#0073e9] ${activeTab === "nonMember" ? "text-[#0073e9]" : ""}}
          >
            비회원 배송조회
          </div>
          {activeTab === "nonMember" && <div className="border-b border-blue-600 pb-2 "></div>}
        </li>
      </ul>

 

중복되는 부분은 li 다 이런 코드는 map으로 돌린다

 

1. 배열 리터럴을 만든다

  const loginTypeList: { key: "email" | "qr" | "nonMember"; label: string }[] = [
    { key: "email", label: "이메일 로그인" },
    { key: "qr", label: "QR코드 로그인" },
    { key: "nonMember", label: "비회원 배송조회" },
  ];

 

2. map으로 돌려돌려

      <ul className="flex flex-row gap-2 text-center px-4">
        {loginTypeList.map(({ key, label }) => (
          <li key={key} className="px-2" onClick={() => setActiveTab(key)}>
            <div className={`hover:text-[#0073e9] ${activeTab === key ? "text-[#0073e9]" : ""}`}>
              {label}
            </div>
            {activeTab === key && <div className="border-b border-blue-600 pb-2 "></div>}
          </li>
        ))}
      </ul>

이렇게 바꾸면

불필요한 반복 없이 깔끔하게 렌더링된다.
key 값으로 탭 전환하고, label로 한글 표시까지 매끄럽게 처리된다.

 

 

[전체 코드]

const AuthMenu = () => {
  const [activeTab, setActiveTab] = useState<"email" | "qr" | "nonMember">("email");

  const loginTypeList: { key: "email" | "qr" | "nonMember"; label: string }[] = [
    { key: "email", label: "이메일 로그인" },
    { key: "qr", label: "QR코드 로그인" },
    { key: "nonMember", label: "비회원 배송조회" },
  ];

  return (
    <div
      className="flex flex-col items-center justify-center text-lg gap-4 py-5 w-fit mx-auto
        border border-gray-200 "
    >
      <h1 className="text-3xl mb-3">로그인</h1>

      {/* <AuthHeader /> */}
      <ul className="flex flex-row gap-2 text-center px-4">
        {loginTypeList.map(({ key, label }) => (
          <li key={key} className="px-2" onClick={() => setActiveTab(key)}>
            <div className={`hover:text-[#0073e9] ${activeTab === key ? "text-[#0073e9]" : ""}`}>
              {label}
            </div>
            {activeTab === key && <div className="border-b border-blue-600 pb-2 "></div>}
          </li>
        ))}
      </ul>

 

덧)

현재 탭이 어떤 상태인지 기억하기 위해  useState를 사용.

useState는 사용자가 클릭한 탭의 상태(email, qr, nonMember)를 기억하고,

그 상태에 따라 어떤 UI를 보여줄지 결정하는 역할이다.

 상태 변경 → 리렌더 → UI 업데이트

 

동작)

이벤트를 걸어서 클릭 이벤트로 상태를 업데이트하고,
→ React가 그에 따라 컴포넌트를 다시 렌더링.

React는 상태가 변경되면 자동으로 렌더링을 "다시" 한다

 

 

 

 

반응형