DateP

옵션 데이터 관리

Solo.dev 2025. 1. 9. 03:41

데이터 관리 설계

DateP 앱에서 메뉴와 세부 옵션 데이터를 효율적으로 관리하기 위해 selectOptions라는 객체를 사용합니다. 이를 통해 선택 가능한 **메뉴(문화, 여가, 식음료, 서비스, 쇼핑, 스포츠)**와 각 메뉴에 대한 세부 옵션을 정의하고 통합 관리합니다.


데이터 관리 방식

  1. SelectOptionsType 타입 정의:
    • selectOptions 객체의 키는 동적으로 접근 가능해야 하므로 [key: string] 형태로 정의.
    • 각 키에 해당하는 값은 { label: string; value: string }[] 배열로 정의.
  2. 데이터 저장:
    • 메뉴는 menu 키에 저장(문화, 여가, 식음료, 서비스, 쇼핑, 스포츠).
    • 각 메뉴에 따른 세부 옵션은 해당 키에 저장.

코드: optionsData.ts

type SelectOptionsType = {
  [key: string]: { label: string; value: string }[];
};

export const selectOptions: SelectOptionsType = {
  // 메뉴 목록
  menu: [
    { label: '문화', value: 'culture' },
    { label: '여가', value: 'leisure' },
    { label: '식음료', value: 'foodanddrink' },
    { label: '서비스', value: 'service' },
    { label: '쇼핑', value: 'shopping' },
    { label: '스포츠', value: 'sports' },
  ],

  // 문화 세부 옵션
  culture: [
    { label: '미술관', value: 'art_gallery' },
    { label: '예술 스튜디오', value: 'art_studio' },
    { label: '강당', value: 'auditorium' },
    { label: '문화적 랜드마크', value: 'cultural_landmark' },
    { label: '역사적인 장소', value: 'historical_place' },
    { label: '기념비', value: 'monument' },
    { label: '박물관', value: 'museum' },
    { label: '공연 예술 극장', value: 'performing_arts_theater' },
    { label: '조각 작품', value: 'sculpture' },
  ],

  // 여가 세부 옵션
  leisure: [
    { label: '익스트림 스포츠 센터', value: 'adventure_sports_center' },
    { label: '야외 공연장', value: 'amphitheatre' },
    { label: '실내 오락실', value: 'amusement_center' },
    { label: '놀이공원', value: 'amusement_park' },
    { label: '수족관', value: 'aquarium' },
    { label: '바비큐 공간', value: 'barbecue_area' },
    { label: '식물원', value: 'botanical_garden' },
    { label: '볼링장', value: 'bowling_alley' },
    { label: '코미디 클럽', value: 'comedy_club' },
    { label: '영화관', value: 'movie_theater' },
    { label: '정원', value: 'garden' },
    { label: '하이킹 코스', value: 'hiking_area' },
    { label: '천문관', value: 'planetarium' },
  ],

  // 식음료 세부 옵션
  foodanddrink: [
    { label: '카페', value: 'cafe' },
    { label: '레스토랑', value: 'restaurant' },
    { label: '디저트 전문점', value: 'dessert_shop' },
    { label: '중식당', value: 'chinese_restaurant' },
    { label: '한식당', value: 'korean_restaurant' },
    { label: '일본 요리 전문점', value: 'japanese_restaurant' },
    { label: '피자 전문점', value: 'pizza_restaurant' },
  ],

  // 서비스 세부 옵션
  service: [
    { label: '바디아트 서비스', value: 'body_art_service' },
    { label: '출장 연회 서비스', value: 'catering_service' },
    { label: '음식 배달 서비스', value: 'food_delivery' },
    { label: '발 관리 서비스', value: 'foot_care' },
    { label: '헤어케어 서비스', value: 'hair_care' },
    { label: '네일샵', value: 'nail_salon' },
  ],

  // 쇼핑 세부 옵션
  shopping: [
    { label: '서점', value: 'book_store' },
    { label: '의류 매장', value: 'clothing_store' },
    { label: '편의점', value: 'convenience_store' },
    { label: '백화점', value: 'department_store' },
    { label: '식료품점', value: 'food_store' },
    { label: '쇼핑몰', value: 'shopping_mall' },
  ],

  // 스포츠 세부 옵션
  sports: [
    { label: '아레나, 실내 스포츠 경기장', value: 'arena' },
    { label: '운동장, 야외 스포츠 필드', value: 'athletic_field' },
    { label: '골프장', value: 'golf_course' },
    { label: '체육관', value: 'gym' },
    { label: '아이스 스케이트장', value: 'ice_skating_rink' },
    { label: '놀이터, 야외 어린이 놀이 시설', value: 'playground' },
    { label: '수영장', value: 'swimming_pool' },
  ],
};

 


데이터 관리 특징

  1. 데이터 분리 및 확장 가능성:
    • 데이터는 menu와 각 메뉴별 옵션으로 분리되어 있어, 새로운 메뉴나 옵션을 쉽게 추가 가능.
  2. 일관성 유지:
    • 모든 메뉴와 옵션 데이터는 optionsData.ts 파일에서 중앙 관리.
    • UI 컴포넌트는 이 데이터를 가져와 동적으로 렌더링.
  3. 타입 안정성:
    • SelectOptionsType을 사용해 동적 키 접근에서도 타입 안전성을 유지.

예제: CustomSelect에서 사용

<Select onValueChange={onValueChange} selectedValue={selectedValue}>
      <SelectTrigger
        variant="outline"
        size="xl"
        style={{
          width: '100%', // 부모 너비에 맞춤
          paddingHorizontal: 10,
          alignItems: 'center',
        }}
      >
        <SelectInput
          placeholder={placeholder}
          style={{
            textAlign: 'left',
            width: '85%', // 텍스트가 아이콘과 겹치지 않도록 너비 조정
            paddingRight: 10,
            fontSize: 14,
            overflow: 'hidden',
            textOverflow: 'ellipsis',
          }}
        />
        <SelectIcon
          as={ChevronDownIcon}
          style={{
            position: 'absolute',
            right: 10,
          }}
        />
      </SelectTrigger>
      <SelectPortal>
        <SelectBackdrop />
        <SelectContent style={styles.selectContent}>
          <ScrollView
            style={styles.scrollContainer}
            contentContainerStyle={styles.scrollContent}
          >
            <SelectDragIndicatorWrapper>
              <SelectDragIndicator />
            </SelectDragIndicatorWrapper>
            {options.map((option) => (
              <SelectItem
                key={option.value}
                label={option.label}
                value={option.value}
                style={styles.selectItem}
              />
            ))}
          </ScrollView>
        </SelectContent>
      </SelectPortal>
    </Select>

결과물

  • selectOptions 객체를 통해 메뉴와 옵션 데이터를 효율적으로 관리.
  • CustomSelect와 연동하여 동적인 메뉴/옵션 선택 UI 구현 가능.
  • 데이터 추가 및 수정이 필요할 경우, optionsData.ts 파일만 수정하면 전체 시스템에 반영.