[React] 다음 주소 API 적용하기
본문 바로가기
더 알아보기/기능

[React] 다음 주소 API 적용하기

by 은돌1113 2022. 3. 28.
728x90

다음 주소 API 사용 할 일이 생겨서 카카오에서 제공 해주는 다음 주소 API를 사용하려고 했으나

이렇게 라이브러리를 script로 제공 해주길래 따로 구글링 해서 React 버전으로 찾았다.

 

아래 블로그를 바탕으로 변형 시켜서 사용하였다.

 

[React] react 에서 우편번호 찾기 api 사용하기 - 떽떽대는 개발공부

오늘은 react 에서 오픈 api 를 사용하여 우편번호 찾기 기능을 구현 해볼 것이다. 다음에서 제공하는 api 를 사용할 것이다. react-daum-postcode 우편번호 검색이라고 되어있는 버튼을 클릭하면 우편번

ddeck.tistory.com


1. 라이브러리 설치

yarn add react-daum-postcode

 

2. 주소창을 구현 할 파일 생성

(예제에서는 파일을 3개로 나누셨지만, 나는 하나의 파일에서 세 개의 컴포넌트로 나눠서 사용했다.)

 

3. 총 3개의 컴포넌트가 있다.

 

1) 버튼과 팝업창의 기준이 되는 → AddressByDaum 컴포넌트

2) react-dom을 사용하여 팝업창을 띄워주는 틀 → PopupDom 컴포넌트

3) 실제로 팝업창을 띄울 페이지 → PopupPostCode 컴포넌트

 

막상 변형 시키다 보니 별거 없었다. CSS 같은 경우는 styled-components 라이브러리를 사용했고, 안에 들어가는 세부적인 코드는 아래와 같이 F12로 필요한 부분만 복붙 해왔다.

 

실행 시켜 보면 아래와 같은 Form이 나오고, 우편번호 찾기 버튼 클릭 시 오른쪽에 다음 주소 API 모달창이 나온다.

 

주소를 입력하고, 클릭하면 address state에 설정한 컬럼 값에 맞게 값이 들어간다.

필요한 값들은 handlePostCode() 함수가 실행되면 data가 반환 되는 데 console.log로 찍어보고 필요한 거 뽑아왔다.


전체 코드

더보기
// yarn add react-daum-postcode 설치 후 아래 코드 복붙해서 사용
// 출처 : https://ddeck.tistory.com/41

import { useState } from "react";
import styled from "styled-components";

import ReactDom from "react-dom";
import DaumPostcode from "react-daum-postcode";

//TODO 1. 버튼과 팝업창의 기준이 될 공간을 하나 만들어 준다.
const AddressByDaum = () => {
  // 팝업창 상태 관리
  const [isPopupOpen, setIsPopupOpen] = useState(false);
  const [address, setAddress] = useState({
    postNumber: "", // 우편 번호
    streetNameAddress: "", // 도로명 주소
    jibunAddress: "", // 지번 주소
    detailedAddress: "", // 상세 주소
    note: "", // 참고사항
  });

  // 팝업창 열고 닫기
  const openPostCode = () => {
    setIsPopupOpen(!isPopupOpen);
  };

  return (
    <AddressForm>
      <div>
        <input
          type="text"
          className="postNumber"
          placeholder="우편번호"
          defaultValue={address.postNumber}
        />
        <button className="findPostAddress" onClick={openPostCode}>
          우편번호 찾기
        </button>
      </div>
      <input
        type="text"
        className="streetNameAddress"
        placeholder="도로명주소"
        defaultValue={address.streetNameAddress}
      />
      <div>
        <input
          type="text"
          className="detailAddress"
          placeholder="상세주소"
          defaultValue={address.detailedAddress}
        />
        <input
          type="text"
          className="note"
          placeholder="참고항목"
          defaultValue={address.note}
        />
      </div>
      {/* 다음 주소 API Form */}
      <div id="popupDom">
        {isPopupOpen && (
          <PopupDom>
            <PopupPostCode
              address={address}
              setAddress={setAddress}
              onClose={openPostCode}
            />
          </PopupDom>
        )}
      </div>
    </AddressForm>
  );
};

const AddressForm = styled.div`
  position: relative;
  margin-top: 500px;
  margin-left: 500px;

  & .postNumber {
    margin: 0.2em 0;
    font-size: 1em;
    padding: 0.5em;
    border: 1px solid #ccc;
    border-color: #dbdbdb #d2d2d2 #d0d0d0 #d2d2d3;
    box-shadow: inset 0.1em 0.1em 0.15em rgb(0 0 0 / 10%);
    vertical-align: middle;
    line-height: 1.25em;
    outline: 0;
    width: 200px;
  }

  & .findPostAddress {
    display: inline-block;
    padding: 0.5em 1em;
    margin: 0.4em 0.15em;
    border: 1px solid #ccc;
    border-color: #dbdbdb #d2d2d2 #b2b2b2 #d2d2d3;
    cursor: pointer;
    color: #464646;
    border-radius: 0.2em;
    vertical-align: middle;
    font-size: 1em;
    line-height: 1.25em;
    background-image: -webkit-gradient(
      linear,
      left top,
      left bottom,
      from(#fff),
      to(#f2f2f2)
    );
  }

  & .streetNameAddress {
    margin: 0.2em 0;
    font-size: 1em;
    padding: 0.5em;
    border: 1px solid #ccc;
    border-color: #dbdbdb #d2d2d2 #d0d0d0 #d2d2d3;
    box-shadow: inset 0.1em 0.1em 0.15em rgb(0 0 0 / 10%);
    vertical-align: middle;
    line-height: 1.25em;
    outline: 0;
    width: 337px;
  }

  & .detailAddress {
    margin: 0.2em 0;
    font-size: 1em;
    padding: 0.5em;
    border: 1px solid #ccc;
    border-color: #dbdbdb #d2d2d2 #d0d0d0 #d2d2d3;
    box-shadow: inset 0.1em 0.1em 0.15em rgb(0 0 0 / 10%);
    vertical-align: middle;
    line-height: 1.25em;
    outline: 0;
    width: 165px;
    margin-right: 5.5px;
  }

  & .note {
    margin: 0.2em 0;
    font-size: 1em;
    padding: 0.5em;
    border: 1px solid #ccc;
    border-color: #dbdbdb #d2d2d2 #d0d0d0 #d2d2d3;
    box-shadow: inset 0.1em 0.1em 0.15em rgb(0 0 0 / 10%);
    vertical-align: middle;
    line-height: 1.25em;
    outline: 0;
    width: 165px;
  }

  & .addressPopUp {
    position: relative;
    width: 500px;
    top: -300px;
    left: 25%;
  }
`;

//TODO 2. 팝업창을 띄울 수 있도록 react-dom을 하나 생성한다.
const PopupDom = ({ children }) => {
  const el = document.getElementById("popupDom");
  return ReactDom.createPortal(children, el);
};

//TODO 3. 실제로 팝업창이 나타날 페이지를 생성한다.
const PopupPostCode = (props) => {
  const { address, setAddress, onClose } = props;

  // 우편번호 검색 후 주소 클릭 시 실행될 함수, data callback 용
  const handlePostCode = (data) => {
    let fullAddress = data.address;
    let extraAddress = "";

    if (data.addressType === "R") {
      if (data.bname !== "") {
        extraAddress += data.bname;
      }
      if (data.buildingName !== "") {
        extraAddress +=
          extraAddress !== "" ? `, ${data.buildingName}` : data.buildingName;
      }
      fullAddress += extraAddress !== "" ? ` (${extraAddress})` : "";
    }

    const postNumber = data.zonecode; // 우편번호
    const streetNameAddress = data.address; // 도로명 주소
    const jibunAddress = data.jibunAddress; // 지번 주소
    const note = `(${data.bname}, ${data.query})`; // 참고항목

    // 주소 선택 시 우편번호, 도로명 주소, 지번 주소, 참고항목 state 저장
    setAddress({
      ...address,
      postNumber: postNumber,
      streetNameAddress: streetNameAddress,
      jibunAddress: jibunAddress,
      detailedAddress: "",
      note: note,
    });

    // 주소 Form창 닫기
    onClose();
  };

  const postCodeStyle = {
    display: "block",
    position: "absolute",
    top: "10%",
    width: "500px",
    height: "600px",
    border: "2px solid #dadada",
  };

  return (
    <div className="addressPopUp">
      <DaumPostcode
        className="modalForm"
        style={postCodeStyle}
        onComplete={handlePostCode}
      />
    </div>
  );
};

export default AddressByDaum;
728x90

댓글