본문 바로가기
개발일지/트친소 생성기 사이트

[원신 X친소표 사이트 제작기] 4. Dropdown 리스트픽 만들기 #React

by 박기린 2024. 12. 4.

 


Dropdown 메뉴

성별과 연령대 정보, 원신 서버 정보를 입력할 때,

사전에 지정된 목록을 사용자가 쉽게 선택할 수 있도록 만들려고 합니다.

 

 

 

 

 

 

 

이때 유용한 디자인이 '드롭다운 메뉴'입니다.

성별의 경우 '남자, 여자, 비공개'를 미리 개발자가 지정한 다음 드롭다운 메뉴로 제공하면, 사용자는 쉽게 목록에서 자신에게 해당되는 걸 선택하면 끝입니다.

 

 

 

 


OneLineDropdown 컴포넌트

          <OneLineDropdown
            placeholder={"성별"}
            value={gender}
            pickList={["남자", "여자", "비공개"]}
            onChange={(e) => setGender(e.target.value)}
          />
          <OneLineDropdown
            placeholder={"연령대"}
            value={age}
            pickList={["성인", "미성년자", "비공개"]}
            onChange={(e) => setAge(e.target.value)}
          />

OneLineDropdown 컴포넌트를 페이지로 호출하면, 위와 같은 DOM이 출력됩니다.

 

 

 

 

OneLineDropdown 소스코드

import { FormText, FormTextContainer } from "@/styles/Texts";
import { OneLineContainer } from "@/styles/Containers";
import styled from "styled-components";
import { Select, SelectContainer } from "@/styles/Inputs";

const OneLineDropdown = (props) => {
  const { placeholder, value, pickList, onChange } = props;
  return (
    <OneLineContainer>
      <FormTextContainer>
        <FormText>{placeholder}</FormText>
      </FormTextContainer>
      <SelectContainer>
        <Select value={value} onChange={onChange}>
          <option value="" disabled>
            선택하세요
          </option>
          {pickList.map((element, idx) => (
            <option key={idx} value={element}>
              {element}
            </option>
          ))}
        </Select>
        <Arrow>▼</Arrow>
      </SelectContainer>
    </OneLineContainer>
  );
};

export default OneLineDropdown;

const Arrow = styled.div`
  position: absolute;
  top: 50%;
  right: 10px;
  transform: translateY(-50%);
  pointer-events: none;
`;

 

 

 

props 설정

  const { placeholder, value, pickList, onChange } = props;

 

부모 컴포넌트로부터 3가지 props를 전달받습니다.

 

placeholder : 드롭다운 필드 왼쪽에 표시할 설명 텍스트입니다.
value : 드롭다운 필드에 표시되는 현재 state 값입니다.

pickList : 드롭다운 메뉴로 출력될 Array List입니다.
onChange : Input Value가 변경될 때 호출되는 함수입니다.

 

 

 

 

JSX 분석

<OneLineContainer>
  <FormTextContainer>
    <FormText>{placeholder}</FormText>
  </FormTextContainer>
  <SelectContainer>
    <Select value={value} onChange={onChange}>
      <option value="" disabled>
        선택하세요
      </option>
      {pickList.map((element, idx) => (
        <option key={idx} value={element}>
          {element}
        </option>
      ))}
    </Select>
    <Arrow>▼</Arrow>
  </SelectContainer>
</OneLineContainer>

 

OneLineContainer
텍스트와 Dropdown을 한 줄로 정렬하는 <div>입니다.
전체 UI의 배치를 담당합니다.

 

 

FormTextContainer
설명 텍스트(FormText)를 감싸는 컨테이너입니다.
Dropdown 옆의 placeholder 텍스트 위치를 조정하는 역할을 합니다.

 

 

FormText
부모로부터 받은 placeholder 값을 표시합니다.
Dropdown의 입력 필드가 무엇을 선택해야 하는지 사용자에게 알려줍니다.

 


SelectContainer
Dropdown 필드와 화살표를 감싸는 <div>입니다.

 


Select

    <Select value={value} onChange={onChange}>
      <option value="" disabled>
        선택하세요
      </option>
      {pickList.map((element, idx) => (
        <option key={idx} value={element}>
          {element}
        </option>
      ))}
    </Select>


사용자가 선택할 수 있는 Dropdown입니다. html에서는 <select> 요소입니다.

아래의 두 가지 props를 받습니다.
- value : 현재 선택된 값을 바인딩합니다.
- onChange : 선택 값이 변경될 때 호출됩니다.

 

Select <option>을 자식 컴포넌트로 받습니다.

<option value="" disabled>
  선택하세요
</option>

맨 처음에는 disabled 옵션으로 '선택하세요' 안내가 표시되게 설정했습니다.

 

 

{pickList.map((element, idx) => (
  <option key={idx} value={element}>
    {element}
  </option>
))}

 

이후엔 전달받은 prop인 pickList 배열을 순회하며 <option> 태그를 생성합니다.

 

 

Arrow

    <Arrow>▼</Arrow>

Dropdown의 화살표 아이콘입니다.

styled-components를 사용해 스타일을 지정합니다
- [position: absolute] : Select 필드 안에서 절대 위치 설정. (top: 50%; right: 10px)
- [transform: translateY(-50%)] : 중앙 정렬.
- [pointer-events: none] : 클릭 이벤트를 무시해 화살표가 선택 불가능하게 만듭니다.

 

 

 

 

Styled-Components

OneLineContainer, FormText, FormTextContainer, SelectContainer, Select 모두 특별한 기능이 추가된 컴포넌트가 아니라, styled-components로 스타일만 입힌 컴포넌트입니다.

스타일 컴포넌트의 코드 전문을 보고 싶으면, 접은 글을 펼치세요.

더보기
const OneLineContainer = styled.div`
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-end;
  width: 300px;
  margin-bottom: 0.7em;
`;

const FormTextContainer = styled.div`
  display: flex;
  flex: 1;
  justify-content: center;
`;

const FormText = styled.text`
  font-size: 19px;
  font-weight: bold;
`;

const SelectContainer = styled.div`
  position: relative;
  width: 225px;
  height: 35px;
`;

const Select = styled.select`
  width: 100%;
  height: 100%;
  padding-left: 10px;
  font-size: 15px;
  background-color: #efecec;
  border: none;
  border-radius: 5px;
  appearance: none; // 기본 드롭다운 화살표 숨기기
  outline: none;
  cursor: pointer;
`;

 

 


작동 구조

값이 없을 땐, '선택하세요'가 떠있습니다.

 

 

드롭다운 메뉴를 누르면, 목록이 뜹니다.

'선택하세요'는 disabled 되어 있습니다.

 

 

 

메뉴를 선택하면, 그 값으로 state가 변경되고, <select>의 value로 지정되어 있기 때문에 변경된 값이 사용자에게 잘 출력됩니다.

 

 

 

반응형