Skip to content

Dropdown

안성재 edited this page Nov 14, 2023 · 1 revision

디자인

image image

실제 구현 코드

function Dropdown({ options, getSelectedValue }) {
  const [isOpen, setIsOpen] = useState(false);
  const [isError, setIsError] = useState(false);
  const [selectedValue, setSelectedValue] = useState(options[0]);
  const ref = useRef(null);

  const handleClickButton = (e) => {
    e.stopPropagation();
    setIsOpen(!isOpen);
  };

  const handleClickOutside = (e) => {
    if (ref.current && !ref.current.contains(e.target)) {
      setIsOpen(false);
    }
  };

  const handleClickListItem = (e) => {
    setSelectedValue(e.target.innerText);
    getSelectedValue(e.target.innerText);
    setIsOpen(false);
  };

  useEffect(() => {
    document.addEventListener("click", handleClickOutside);
    return () => {
      document.removeEventListener("click", handleClickOutside);
    };
  }, []);

  return (
    <S.DropdownContainer>
      <S.ButtonContainer
        $active={isOpen}
        $error={isError}
        onClick={handleClickButton}
      >
        <p>{selectedValue}</p>
        {isOpen ? (
          <img src={arrowUp} alt="위 화살표" />
        ) : (
          <img src={arrowDown} alt="아래 화살표" />
        )}
      </S.ButtonContainer>
      {isError && <S.ErrorMessage>Error Message</S.ErrorMessage>}
      {isOpen && (
        <S.ListContainer ref={ref}>
          {options.map((value, index) => (
            <S.ListItem key={index} onClick={handleClickListItem}>
              {value}
            </S.ListItem>
          ))}
        </S.ListContainer>
      )}
    </S.DropdownContainer>
  );
}

설명

  • 드롭다운 컴포넌트는 값을 자유롭게 작성받을 수 있는 Input 컴포넌트와 다르게 이미 정해져 있는 값들 중에서 하나를 선택할 때 사용하는 컴포넌트입니다.
  • 예를 들어 사용자가 4개의 선택지가 존재하는 폰트 중 하나를 고르도록 하는 기능을 구현할 때 사용할 수 있습니다.
  • 화면에 항상 보여지는 버튼 영역과 isOpen state를 통해 열고 닫히는 리스트 영역으로 나누어져 있습니다.
  • options prop을 통해 배열을 받아서, 리스트가 보여지는 경우 해당 배열이 렌더링되도록 합니다.
  • selectedValue state를 통해 리스트에서 선택된 값이 버튼에 보여지도록 했습니다.
  • 버튼을 통해 드롭다운이 열고 닫히도록 하고, 추가로 useRef를 사용해서 드롭다운이 열려있을 때 화면의 바깥 영역을 눌렀을 때도 자연스럽게 닫히도록 했습니다.
  • 스타일드 컴포넌트에 isOpen, isError, disabled prop을 전달해서 상황에 따라 다르게 스타일링되도록 했습니다.

컴포넌트

페이지

Clone this wiki locally