카테고리 없음

[Refactor] 다음 카카오 주소검색 API 적용 컴포넌트 수정

jeong_ga 2022. 11. 4. 14:39
  • company만 적용해놨던 주소 검색 기능을 user 컴포넌트에도 사용하기 위해 해당 주소검색 팝업 컴포넌트를 수정함.
    • 적용 중 오류가 있어 해당 오류를 함께 수정함

 

기존에 작성했던 코드

 

[Feat & Refactor]다음카카오 주소검색 API(지번주소, 도로명주소, 우편번호)가져오기 & 위도경도 좌표

해결한 문제 다음카카오의 주소 검색 API를 통해 주소를 검색하여 입력기능 추가 입력 칸의 submit 시 좌표를 가져오는 코드 순서를 주소 검색 시 좌표를 가져와 입력하도록 수정 // 카카오 API, 주

jeong-ga.tistory.com

 

구현 화면

 

company, user는 필요한 정보가 달라 그에 맞게 return되는 요소 & 서버에 전송하는 data를 다르게 하였다.

 

 

코드

setUser.js

<label htmlFor="address" className="blockLabel">
    주소
</label>
<PieceRegisterSearchPopUp
userComponent
setMultilAddress={setMultilAddress}
multilAddress={multilAddress}
getedData={getedData}
/>

 

setComapny.js

<label htmlFor="address" className=" blockLabel">
    주소
</label>
<PieceRegisterSearchPopUp
setMultilAddress={setMultilAddress}
multilAddress={multilAddress}
getedData={getedData}
/>

 

하위 컴포넌트

import React from "react";
import { useEffect } from "react";
import { useDaumPostcodePopup } from "react-daum-postcode";

export default function Postcode({
  userComponent,
  setMultilAddress,
  multilAddress,
  getedData,
}) {
  // 다음 주소 검색 API 주소
  const scriptUrl =
    "//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js";
  // eact-daum-postcode의 popup 방식 사용
  const open = useDaumPostcodePopup(scriptUrl);
  // 부모 컴포넌트에게 값을 전달하기 위해 함수로 사용
  function fnSetAddress(address) {
    setMultilAddress(address);
  }

  // 카카오 API, 주소를 위도 경도로 변환
  const callMapcoor = (res) => {
    var geocoder = new window.kakao.maps.services.Geocoder();
    var callback = function (result, status) {
      if (status === window.kakao.maps.services.Status.OK) {
        // 공사콕에서 사용하는 key와 다음 카카오의 키가 다름!
        // 다음 카카오 신주소 : roadAddress, 구주소 :jibunAddress, 우편번호 : zonecode
        console.log(res);
        fnSetAddress({
          address: res.roadAddress,
          oldaddress: res.jibunAddress,
          zipcode: res.zonecode,
          latitude: Math.floor(result[0].y * 100000),
          longitude: Math.floor(result[0].x * 100000),
        });
      }
    };
    geocoder.addressSearch(res.address, callback);
  };

  useEffect(() => {
    // setUser는 주소값만 저장함
    if (getedData !== [] && userComponent) {
      fnSetAddress({
        address: getedData.address,
      });
    }
    // setCompany는 아래와 같은 정보가 필요함
    if (getedData !== [] && !userComponent) {
      //  신주소 : address, 구주소 :oldaddress, 우편번호 : zipcode
      fnSetAddress({
        address: getedData.address,
        oldaddress: getedData.oldaddress,
        zipcode: getedData.zipcode,
        longitude: getedData.longitude,
        latitude: getedData.latitude,
      });
    }
  }, [getedData]);

  // 팝업 입력창에 값을 입력하면 작동하는 함수
  const handleComplete = (data) => {
    // setUser는 주소값만 저장함
    if (userComponent) {
      fnSetAddress({
        address: data.roadAddress,
      });
    }
    // setCompany는 아래와 같은 정보가 필요함
    if (!userComponent) {
      // 팝업 입력창에 값을 입력하면 해당 주소로 좌표를 구함
      callMapcoor(data);
    }
  };

  const handleClick = () => {
    open({ onComplete: handleComplete });
  };

  // setUser
  if (!!userComponent) {
    return (
      <>
        <input
          type="text"
          id="roadAddress"
          disabled
          value={multilAddress.address || ""}
        />
        <button
          type="button"
          onClick={handleClick}
          style={{ backgroundColor: "red" }}
        >
          Open
        </button>
      </>
    );
  }

  // setCompany
  if (!userComponent) {
    return (
      <>
        <input
          type="text"
          id="roadAddress"
          disabled
          value={multilAddress.address || ""}
        />
        <input
          type="text"
          id="zipcode"
          value={multilAddress.zipcode || ""}
          disabled
        />

        <button
          type="button"
          onClick={handleClick}
          style={{ backgroundColor: "red" }}
        >
          Open
        </button>

        <div className="formContentWrap">
          <label htmlFor="address" className=" blockLabel">
            좌표
          </label>
          <ul className="detailContent" style={{ display: "flex" }}>
            <li>
              <span>위도</span>
              <input
                type="text"
                disabled
                placeholder="위도 값이 없습니다."
                value={multilAddress.latitude || ""}
              />
            </li>
            <li>
              <span>경도</span>
              <input
                type="text"
                disabled
                placeholder="경도 값이 없습니다."
                value={multilAddress.longitude || ""}
              />
            </li>
          </ul>
        </div>
      </>
    );
  }
}
  • user와 company는 필요한 정보가 달라 useEffect, return tag, handleComplate 함수 내 조건을 걸어 다르게 동작하도록 설정하였다.

 

만난 오류

처음 user 컴포넌트에게 해당 컴포넌트를 추가하니 400 오류가 발생하였다. company도 동작하지 않기에 API나 라이브러리 오류인줄 알았으나, 기존 값이 없는 경우 해당 오류가 발생하는 것을 확인하여 좌표를 구하는 카카오 API 함수 내 코드를 수정하고 (원래는 res.address가 아닌 multiAddress.address로 작성하여 생긴 오류였다.) useEffect 내 조건을 추가하여 기존 값을 가져올 때 useState내 코드가 다르게 작성되도록 수정하였다.