select box에서 dropdown의 option 개수 조절하기

10218 단어 ReactReact

하고 있는 프로젝트에서 select box를 클릭하면 나오는 dropdown에 option들이 보이는 개수를 5개로 지정해야 될 일이 있었다. 별거 아닌거 같지만 꽤 시간 들여 했어서... 기록한다 🙃


1. <select size={num}>

보이는 option들의 개수를 지정하고 싶을 때 사용하는 가장 간단한 방법이다. 하지만... 이 방법은 클릭했을 때 dropdown이 나오는 것이 아니라, 처음부터 지정한 개수로 dropdown이 펼쳐져 있다. 고로 나에게는 해결방법으로 적절하지 않았다.

간단한 데모: http://www.tcpschool.com/html-tag-attrs/select-size


2. useRef와 focusEvent

다른 방법이 있나 찾아보던 중에, stackoverflow에서 위와 같은 글을 봤다. 저 글 작성자분께서 소중한 데모 링크도 첨부해주셨다. (참고로 원글은 맨 아래 레퍼런스에 링크 남겨놨음!)

다만 나는 React로 만들어진 프로젝트 내에서 작업하므로 저대로 사용할 순 없다! 그치만 해결법은 찾은 이상 살짝 바꾸는 건 일도 아니다.

this 대신 useRef 사용하기

난 함수형 컴포넌트를 사용하고 있으므로 this를 사용할 수 없다. 대신 내가 가리키고자 하는 element를 지칭할 수 있도록 useRef를 사용해주면 된다. 그리고 아래와 같이 해주면 된다.

import { useRef } from 'react';

const SelectBox = (props: SelectBoxProps) => {
  const selectBox = useRef() as React.MutableRefObject<HTMLSelectElement>;

  return (
    <>
      <SelectBoxStyled {...props}>
        <select
          ref={selectBox}
          onFocus={() => {
            selectBox.current.size = 5;
          }}
          onBlur={() => {
            selectBox.current.size = 1;
          }}
          onChange={(e) => {
            selectBox.current.size = 1;
            selectBox.current.blur();
          }}
        >
      </SelectBoxStyled>
    </>
  );
};

export default SelectBox;

CSS 수정하기

이제 select box를 클릭했을 때 dropdown에 내가 원하는 개수의 option들이 나온다. 하지만 이와 같은 방식은... 위 사진처럼... dropdown이 늘어나는 만큼 select box 자체가 늘어난다... 그래서 난 아래와 같이 수정해주었다.

//SelectBox.tsx
return (
  <>
    <SelectBoxStyled {...props}>
      <div className="select-wrap">
        <select { /*생략*/ }>
          <option value="">{props.subject}</option>
          {props.options ? props.options.map((option, idx) => (
              <option key={idx} value={option}>{option}</option>
            ))
          : null}
        </select>
      </div>
    </SelectBoxStyled>
  </>
);
//SelectBoxStyled.tsx
export const SelectBoxStyled = styled.div<SelectBoxProps>`
  position: relative;
  display: inline-block;
  .select-wrap {
    position: absolute;
  }
  select {
    display: inline-block;
  }
`;

position 속성을 활용해주었다. 그럼 가장 상단에 첨부했던 아름다운 select box가 나온다! (이게 뭐라고 2시간 동안 했다 ㅜㅜ) select box 커스텀 해본 건 처음이었는데 재밌는 경험이었당.


레퍼런스

좋은 웹페이지 즐겨찾기