언어/Next.js

[react-select] 리액트 셀렉트 사용해보기

홍시_코딩기록 2024. 7. 7. 22:20

나는 드롭다운으로 지역을 선택하는 것을 만들고 싶었다.

셀렉트박스를 커스텀할 수 있는 방법을 찾아보다 리액트 셀렉트를 발견

 

대한민국 행정구역 파일도 찾으면 있을 거라 생각해서 json을 찾았다가 변수로 정의된 코드를 찾았음.

export const AREA0 = ['전체', '서울', '인천', '대전', '광주', '대구', '울산', '부산', '경기', '강원', '충북', '충남', '전북', '전남', '경북', '경남', '제주'];
export const AREA1 = ['강남구','강동구','강북구','강서구','관악구','광진구','구로구','금천구','노원구','도봉구','동대문구','동작구','마포구','서대문구','서초구','성동구','성북구','송파구','양천구','영등포구','용산구','은평구','종로구','중구','중랑구',
];
export const AREA2 = ['계양구', '남구', '남동구', '동구', '부평구', '서구', '연수구', '중구', '강화군', '옹진군'];
export const AREA3 = ['대덕구', '동구', '서구', '유성구', '중구'];
export const AREA4 = ['광산구', '남구', '동구', '북구', '서구'];
export const AREA5 = ['남구', '달서구', '동구', '북구', '서구', '수성구', '중구', '달성군'];
export const AREA6 = ['남구', '동구', '북구', '중구', '울주군'];
export const AREA7 = ['강서구', '금정구', '남구', '동구', '동래구', '부산진구', '북구', '사상구', '사하구', '서구', '수영구', '연제구', '영도구', '중구', '해운대구', '기장군'];
export const AREA8 = ['고양시','과천시','광명시','광주시','구리시','군포시','김포시','남양주시','동두천시','부천시','성남시','수원시','시흥시','안산시','안성시','안양시','양주시','오산시','용인시','의왕시','의정부시','이천시','파주시','평택시','포천시','하남시','화성시','가평군','양평군','여주군','연천군',
];
export const AREA9 = ['강릉시', '동해시', '삼척시', '속초시', '원주시', '춘천시', '태백시', '고성군', '양구군', '양양군', '영월군', '인제군', '정선군', '철원군', '평창군', '홍천군', '화천군', '횡성군'];
export const AREA10 = ['제천시', '청주시', '충주시', '괴산군', '단양군', '보은군', '영동군', '옥천군', '음성군', '증평군', '진천군', '청원군'];
export const AREA11 = ['계룡시', '공주시', '논산시', '보령시', '서산시', '아산시', '천안시', '금산군', '당진군', '부여군', '서천군', '연기군', '예산군', '청양군', '태안군', '홍성군'];
export const AREA12 = ['군산시', '김제시', '남원시', '익산시', '전주시', '정읍시', '고창군', '무주군', '부안군', '순창군', '완주군', '임실군', '장수군', '진안군'];
export const AREA13 = ['광양시', '나주시', '목포시', '순천시', '여수시', '강진군', '고흥군', '곡성군', '구례군', '담양군', '무안군', '보성군', '신안군', '영광군', '영암군', '완도군', '장성군', '장흥군', '진도군', '함평군', '해남군', '화순군'];
export const AREA14 = ['경산시','경주시','구미시','김천시','문경시','상주시','안동시','영주시','영천시','포항시','고령군','군위군','봉화군','성주군','영덕군','영양군','예천군','울릉군','울진군','의성군','청도군','청송군','칠곡군',
];
export const AREA15 = ['거제시', '김해시', '마산시', '밀양시', '사천시', '양산시', '진주시', '진해시', '창원시', '통영시', '거창군', '고성군', '남해군', '산청군', '의령군', '창녕군', '하동군', '함안군', '함양군', '합천군'];
export const AREA16 = ['서귀포시', '제주시', '남제주군', '북제주군'];
export const AREA17 = ['전체']

export const regionMapping = {
  '전체': AREA17,
  '서울': AREA1,
  '인천': AREA2,
  '대전': AREA3,
  '광주': AREA4,
  '대구': AREA5,
  '울산': AREA6,
  '부산': AREA7,
  '경기': AREA8,
  '강원': AREA9,
  '충북': AREA10,
  '충남': AREA11,
  '전북': AREA12,
  '전남': AREA13,
  '경북': AREA14,
  '경남': AREA15,
  '제주': AREA16,
};

 

- AREA0은 광역시도 배열이고 

- 1부터 17까지는 하위 지역들 배열이다.

- regionMapping으로 광역시도와 하위 지역들을 매핑해줬다.

 

import { useState } from "react";
import Select from "react-select";
import type { SingleValue } from "react-select";
import { AREA0, regionMapping } from "../../commons/data/subArea";

// const options = [ 기본 옵션 정의
//   { value: "chocolate", label: "Chocolate" },
//   { value: "strawberry", label: "Strawberry" },
//   { value: "vanilla", label: "Vanilla" },
// ];

// 옵션 타입 정의
interface Option {
  value: string;
  label: string;
}

// 드롭다운 옵션
const createOptions = (areas: string[]): Option[] =>
  areas.map((area) => ({
    value: area,
    label: area,
  }));

export default function DropDown() {
  // 광역시
  const [selectedRegion, setSelectedRegion] =
    useState<SingleValue<Option>>(null);
  // 행정구역
  const [subRegions, setSubRegions] = useState<Option[]>([]);
  // 광역시 선택시 행정구역 리셋
  const [subRegionReset, setSubRegionReset] =
    useState<SingleValue<Option>>(null);

  // 광역시도 onChange
  const onChangeRegion = (selectedOption: SingleValue<Option>) => {
    setSelectedRegion(selectedOption);
    setSubRegionReset(null);
    if (selectedOption) {
      const subAreas =
        regionMapping[selectedOption.value as keyof typeof regionMapping];
      setSubRegions(createOptions(subAreas));
    } else {
      setSubRegions([]);
    }
  };

  // 행정구역 onChange
  const onChangeSubRegion = (selectedOption: SingleValue<Option>) => {
    setSubRegionReset(selectedOption);
  };

  return (
    <>
      <Select
        instanceId="main_select"
        options={createOptions(AREA0)}
        onChange={onChangeRegion}
        placeholder="광역시도 선택"
      />
      <Select
        instanceId="sub_select"
        options={subRegions}
        value={subRegionReset}
        onChange={onChangeSubRegion}
        placeholder="하위 지역 선택"
        isDisabled={!selectedRegion}
      />
    </>
  );
}

- options 기본 옵션 정의가 어떻게 들어가는지 보여주려고 넣어놓음.

- createOptions : 문자열 배열을 받아서 객체 배열로 변환.

-  <SingleValue<Option>> react-select에서 정의된 옵션으로 단일 항목 선택 옵션으로 들어감.

 옵션 타입은 내가 정의해놓은 value와 label

- onChangeRegion  광역시도 드롭다운이 onChange되면 AREA0의 배열이 들어간다.

 하위목록 드롭다운은 리셋 시켜주려고 setSubRegionReset(null)을 넣음.

 광역시도 옵션이 선택되면 하위지역 드롭다운의 옵션이 생성된다.

- onChangeSubRegion  하위지역 드롭다운 onChange되면 value값으로 선택한 지역 넣어주기.

- 광역시도 먼저 선택되게 하려고 isDisabled로 광역시도 선택 안되면 비활성화 되게 함.