[TIL #48 기업 협업] 조건부 SelectBox (with graphQL 데이터)

Whoyoung90·2021년 5월 1일
1
post-thumbnail
post-custom-banner

210430 WECODE #48 기업협업 15일차

[TIL #43] 에서는 Apollo Client를 이용하여
백엔드의 graphQL 데이터를 받아오는 연습을 하였고

이 데이터를 활용하여 행정구역 SelectBox를 구현 중이다.

조건부로 데이터를 받아서 뽑아내야 하다보니 생각보다 어렵고

구현된 사항까지만 작성해보겠다.

useEffect(() => { data && setUsers(data.getDestonation.gunGu); }, [data]);

이전 게시글에서 Apollo Client를 통해 받아온 "군/구" 데이터를 셀렉트 박스에 적용하기 위해

// pages/freight-fare.tsx
const ARRAY = {
  siDo: [
    "강원도", "경기도", "경상남도", "경상북도", "광주광역시", 
    "대구광역시", "대전광역시", "부산광역시", "서울특별시",
    "세종특별자치시", "울산광역시", "전라남도", "전라북도", "충청남도", "충청북도",
   ]
}
  • 일단 "시/도" 에 해당하는 셀렉트박스는 프론트엔드에서 하드코딩으로 작성하고

className은 tailwind css를 적용한 상황

// pages/freight-fare.tsx
 <div className="flex flex-row m-3 leading-loose align-middle ">
   <section>행선지</section>
   <select
     {...register("siDo")}
     onChange={categoryChange}
     className="ml-10"
     required

     <option value="">선택</option>
     {ARRAY.siDo.map((el) => (
       <option value={el}>{el}</option>
     ))}
   </select>

   <select id="plusGunGu" className="ml-10" {...register("gunGu")}>
     <option value="">선택</option>
   </select>

   <select className="ml-10" {...register("dong")}>
    <option value="">선택</option>
   </select>
 </div>
  • {ARRAY.siDo.map((el) => ( <option value={el}>{el}</option> ))} : 첫번째 셀렉트 박스는 직접 하드코딩한 시/도 데이터를 map함수로 뿌려주고

  • onChange={categoryChange} :
    onchange함수를 이용하여 "시/도" 데이터를 누를때마다
    해당하는 graphQL의 "군/구" 데이터를 받아오도록
    만들었다.

  • <select id="plusGunGu" ...> "군/구" 셀렉트 박스에는 id값을 설정하여 데이터가 뿌려질 수 있도록 작성

// pages/freight-fare.tsx
import React, { useState, useEffect } from "react";
import { useForm } from "react-hook-form";
import { useQuery, gql } from "@apollo/client";
import { LOAD_REGIONS } from "./graphQL/query";

export function FreightFare() {
  const [users, setUsers] = useState([]);

  const { data } = useQuery(LOAD_REGIONS);

  useEffect(() => {
    data && setUsers(data.getDestonation.gunGu);
    //console.log("쿼리정보", data);
  }, [data]);

  const categoryChange = (e: any) => {
    var test: any = [];
    //console.log(e.target.value);

    if (e.target.value === ARRAY.siDo[0]) {
      test = users;
    } else if (e.target.value === ARRAY.siDo[1]) {
      test = users;
    } else if (e.target.value === ARRAY.siDo[2]) {
      test = users;
    }
  • setUsers(data.getDestonation.gunGu)로 grpahQL 데이터를 받아오고

  • onchange 함수을 설정했던 categoryChange함수를 작성한다. (categoryChange함수는 "시/도" 셀렉트박스에 걸려있음!!)

  • e.target.value : "시/도" 셀렉트 박스에서 클릭한 데이터 값( ex :"강원도" "경기도" "경상남도")

  • e.target.value === ARRAY.siDo[0] : 클릭한 값이 "강원도"와 같다면
    변수 test값은 해당하는 "군/구" 데이터를 받는다.
    (users가 useEffect로 업데이트!)

// pages/freight-fare.tsx
 let list = document.getElementById("plusGunGu");

 test.forEach((el) => {
   let opt = document.createElement("option");
   opt.value = el;
   opt.innerHTML = el;
   list?.appendChild(opt);
 });
  • 위에서 "군/구" 셀렉트 박스에 < select id="plusGunGu" > id를 설정 했었다.

  • 변수 test 에 받아진 "군/구" 데이터를 forEach함수를 사용하여 셀렉트박스의 option 값을 만들어준다.

    • document.getElementById("plusGunGu")를 작성하여 해당 id값에 접근!

지금까지 완성한 내용을 정리해보면
강원도를 누를시 강원도에 해당하는 "시/군" 데이터
경기도를 누를시 경기도에 해당하는 "시/군" 데이터가 나온다.

????

data && setUsers(data.getDestonation.gunGu);
받아온 데이터를 확인해보면

[ { __typename: "SafeRate", gunGu: "강릉시" }, ... ]

배열안 객체마다 __typenamegunGu로 또 나뉘어있다 ^^;

내가 필요한건 gunGu의 value값!!!

접근해보자

  • gunGu에서 gunGu[0].gunGu로 접근해야 받아올 수 있다는 걸 console.log로 확인하고

  • for문을 이용하여 새로운 배열 arr로 추출하였다.

이걸 적용해보면 해당하는 값이 들어온다!

> 정리

로직을 순서대로 정리하여보면

  • "시/도" 셀렉트박스에서 선택한 e.target.value값과 일치하는 "시/도" 데이터가 있다면
    변수 test값으로 해당하는 "시/군"데이터가 들어오고
    [{ __typename: "SafeRate", gunGu: "수원시 장안구" }]

  • for문을 활용하여 내가 원하는 데이터를
    새로운 배열 arr에 새롭게 추출한다.
    ["수원시 장안구"]

  • 추출한 "시/군" 배열 데이터를
    해당 셀렉트박스의 id로 접근하여 forEach함수로 데이터를 뿌려준다.

graphQL로 받은 데이터를 아직 "시/도 => 군/구" 밖에 적용하지 못한 상태이고

그것마저 "경기도, 강원도, 경상남도"만 가능하도록 짜여진 상태이다.

지금은 아직 완성도가 매우 부족한 상황이지만
Apollo Client를 처음 접한 상황에서 배운 것들이 많아서
이렇게 정리하여 보았다.

추가 구현 목표 : 나머지 "시/도 + "군/구 => 동"

profile
비전공으로 일식 쉐프가 되었듯, 배움에 겸손한 프론트엔드 개발자가 되겠습니다 :)
post-custom-banner

0개의 댓글