관리 메뉴

B_log

🔽 React + Tailwind로 드롭다운 만들기 (Dropdown 컴포넌트) 본문

카테고리 없음

🔽 React + Tailwind로 드롭다운 만들기 (Dropdown 컴포넌트)

B_log 2025. 5. 18. 14:51

🔽 React + Tailwind로 드롭다운 만들기 (Dropdown 컴포넌트)

이번 글에서는 React와 Tailwind CSS를 사용해
간단하면서도 커스터마이징 가능한 드롭다운(Dropdown) 컴포넌트를 만드는 방법을 소개합니다.


✅ 완성 기능 요약

  • 버튼 클릭 시 목록이 아래로 펼쳐짐
  • 항목 클릭 시 해당 항목 선택 및 드롭다운 닫힘
  • 선택된 값 표시
  • 외부 클릭 시 자동 닫힘
  • Tailwind CSS로 쉽게 커스터마이징 가능

📁 파일 구조

components/
  └── Dropdown.jsx
App.jsx

🧩 1. Dropdown 컴포넌트 (Dropdown.jsx)

import React, { useState, useRef, useEffect } from 'react'

function Dropdown({ options = [], placeholder = '선택하세요', onSelect }) {
  const [isOpen, setIsOpen] = useState(false)
  const [selected, setSelected] = useState(null)
  const dropdownRef = useRef(null)

  const handleSelect = (option) => {
    setSelected(option)
    setIsOpen(false)
    onSelect?.(option)
  }

  // 바깥 클릭 시 닫힘
  useEffect(() => {
    function handleClickOutside(e) {
      if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
        setIsOpen(false)
      }
    }
    document.addEventListener('mousedown', handleClickOutside)
    return () => document.removeEventListener('mousedown', handleClickOutside)
  }, [])

  return (
    <div ref={dropdownRef} className="relative w-full">
      <button
        onClick={() => setIsOpen((prev) => !prev)}
        className="w-full px-4 py-3 bg-gray-100 rounded-xl text-left text-sm font-medium text-gray-800 hover:bg-gray-200 transition"
      >
        {selected?.label || placeholder}
      </button>

      {isOpen && (
        <ul className="absolute z-10 mt-2 w-full bg-white shadow-md rounded-xl border border-gray-200">
          {options.map((option) => (
            <li
              key={option.value}
              onClick={() => handleSelect(option)}
              className="px-4 py-2 text-sm hover:bg-gray-100 cursor-pointer rounded-xl"
            >
              {option.label}
            </li>
          ))}
        </ul>
      )}
    </div>
  )
}

export default Dropdown

🧪 2. 사용 예시 (App.jsx)

import { useState } from 'react'
import Dropdown from './components/Dropdown'

function App() {
  const [selectedOption, setSelectedOption] = useState(null)

  const options = [
    { label: '한국어', value: 'ko' },
    { label: 'English', value: 'en' },
    { label: '日本語', value: 'ja' },
  ]

  return (
    <div className="min-h-screen bg-gray-50 flex items-center justify-center p-6">
      <div className="w-full max-w-xs space-y-4">
        <Dropdown
          options={options}
          placeholder="언어를 선택하세요"
          onSelect={(option) => {
            setSelectedOption(option)
            console.log('선택됨:', option)
          }}
        />
        {selectedOption && (
          <p className="text-sm text-gray-600">선택한 언어: {selectedOption.label}</p>
        )}
      </div>
    </div>
  )
}

export default App

🎨 커스터마이징 포인트

항목 적용 클래스
버튼 색상 bg-gray-100, hover:bg-gray-200
선택 목록 스타일 hover:bg-gray-100, text-sm, rounded-xl
위치 조절 absolute mt-2 → 필요 시 bottom-full

✅ 마무리

Tailwind CSS와 React만으로도 드롭다운 UI를 충분히 유연하게 구현할 수 있습니다.
기본적인 상태 관리와 DOM 이벤트만 다루면, 외부 라이브러리 없이도 실용적인 드롭다운을 만들 수 있죠!


📌 다음 글 예고

  • Select 컴포넌트를 form과 연결하는 방법
  • ✅ 항목에 아이콘 추가하기
  • ✅ 드롭다운을 모달/툴팁으로 확장하기

필요하신 기능이 있다면 댓글로 남겨주세요 😊