[React] 다음 우편번호 서비스 API (react-daum-postcode)로 주소 입력받기

@eunjios·2023년 10월 17일
2
post-thumbnail

많은 웹 사이트에서 보이는 다음 우편번호 서비스 API를 사용해보자. 참고로 리액트에서 쓸 수 있는 react-daum-postcode 패키지가 있어서 이 패키지를 사용했다.

1. 설치

npm

npm install react-daum-postcode

yarn

yarn add react-daum-postcode

2. 사용

react-daum-postcode를 사용하면 다음 우편번호 서비스 API를 리액트 컴포넌트처럼 이렇게 <DaumPostcode /> 사용할 수 있다.

예시

import DaumPostcode from 'react-daum-postcode';

const addressInput = () => {
  return (
    <div>
      <DaumPostcode />
    </div>
  );
}



그럼 이제 <DaumPostcode />로 넘길 수 있는 props에 대해 알아보자.

theme

다음 우편번호 서비스 화면의 색상 테마를 변경하는 props

테마 지정 객체는 다음과 같이 지정할 수 있다. 주석처리 하거나 빈 문자열로 둘 경우 기본 테마를 따른다. 테마 변경 마법사로 간단히 테마 객체를 만들 수 있다.

const themeObj = {
   bgColor: "", 			// 바탕 배경색
   searchBgColor: "", 		// 검색창 배경색
   contentBgColor: "", 		// 본문 배경색(검색결과,결과없음,첫화면,검색서제스트)
   pageBgColor: "", 		// 페이지 배경색
   textColor: "", 			// 기본 글자색
   queryTextColor: "", 		// 검색창 글자색
   postcodeTextColor: "", 	// 우편번호 글자색
   emphTextColor: "", 		// 강조 글자색
   outlineColor: "" 		// 테두리
};

예시

import DaumPostcode from 'react-daum-postcode';

const addressInput = () => {
  const themeObj = {
   postcodeTextColor: "#FA7142",
   emphTextColor: "#333333",
  };
  return (
    <div>
      <DaumPostcode 
        theme={themeObj}
      />
    </div>
  );
}

style

우편번호 검색창을 감싸는 최상위 엘리먼트 스타일(CSS)을 지정하는 props

기존 스타일 props와 동일하게 스타일 객체를 작성하면 된다.

const style = { width:"100%", height:400 }; // default

예시

import DaumPostcode from 'react-daum-postcode';

const addressInput = () => {
  const style = {
    width: "400px",
    height: "600px",
    border: "1.4px solid #333333",
  };
  return (
    <div>
      <DaumPostcode 
        style={style}
      />
    </div>
  );
}

onComplete

우편번호 검색 결과 목록에서 특정 항목을 클릭한 경우, 해당 정보를 받아서 처리할 콜백 함수를 정의하는 props

onComplete 가 정의되지 않으면 아무 일도 일어나지 않는다. 따라서 onComplete 에 해당하는 콜백함수를 반드시 지정해줘야 한다.

다음 가이드oncomplete 정의 방법은 다음과 같다.

new daum.Postcode({
    oncomplete: function(data) {
        //data는 사용자가 선택한 주소 정보를 담고 있는 객체이며, 상세 설명은 아래 목록에서 확인하실 수 있습니다.
    }
});

즉, oncompletedata를 입력으로 받는 함수이며, 이 data는 주소 정보를 담고 있다. 이를 참고하여 리액트에서 사용할 콜백함수를 정의해보자.

우선 data 에 어떤 정보가 있는지 확인하기 위해 간단히 콘솔 로그를 찍어보자.

const completeHandler = (data) => {
  console.log(data);
}

data 출력 결과

위와 같이 (방대한 양의) 데이터가 찍힌다. 이 중 필요한 속성만 사용하면 된다. 나는 간단히 주소 인풋만 받는 용도로 사용해서 dataaddresszonecode 만 사용했다.

예시

import DaumPostcode from 'react-daum-postcode';

const addressInput = (props) => {
  const completeHandler = (data) => {
    { address, zonecode } = data;
    props.setAddress(address);
    props.setZonecode(zonecode);
  };
  return (
    <div>
      <DaumPostcode 
        onComplete={completeHandler}
      />
    </div>
  );
}

onClose

우편번호 찾기 화면을 팝업으로 띄운 후, 검색 결과를 선택하거나 브라우저의 닫기버튼을 통해 닫았을 때 발생하는 콜백함수를 정의하는 props

다음 가이드의 oncomplete 정의 방법은 다음과 같다.

new daum.Postcode({
    onclose: function(state) {
        if(state === 'FORCE_CLOSE'){
            // code
        } else if(state === 'COMPLETE_CLOSE'){
            // code
        }
    }
});

여기서 state란 우편번호 찾기 화면이 어떻게 닫혔는지에 대한 상태 변수로 COMPLETE_CLOSEFORCE_CLOSE 값 중 하나를 가진다.

  • FORCE_CLOSE
    • 사용자가 브라우저 닫기 버튼을 통해 팝업창을 닫은 상태
  • COMPLETE_CLOSE
    • 사용자가 검색결과를 선택하여 팝업창이 닫힌 상태
    • oncomplete 콜백 함수가 실행 완료된 후에 onclose 실행

예시

state에 따라 다르게 처리할 수 있지만 일단 동일한 동작을 하게 했다.

import { useState } from 'react';
import DaumPostcode from 'react-daum-postcode';

const addressInput = () => {
  const [isOpen, setIsOpen] = useState(false);
  
  const closeHandler = (state) => {
    if (state === 'FORCE_CLOSE') {
      setIsOpen(false);
      console.log('FORCE_CLOSE');
    } else if (state === 'COMPLETE_CLOSE') {
      setIsOpen(false);
      console.log('COMPLETE_CLOSE');
    }
  };
  return (
    <div>
      <DaumPostcode 
        onClose={closeHandler}
      />
    </div>
  );
}

3. 전체 코드 예제

/** @jsxImportSource @emotion/react */
import React, { useState } from 'react';
import DaumPostcode from 'react-daum-postcode';

const AddressInput = (props) => {
  const [zodecode, setZonecode] = useState('');
  const [address, setAddress] = useState('');
  const [isOpen, setIsOpen] = useState('false');

  const themeObj = {
    bgColor: '#FFFFFF', 
    pageBgColor: '#FFFFFF', 
    postcodeTextColor: '#C05850',
    emphTextColor: '#222222',
  };

  const postCodeStyle = {
    width: '360px',
    height: '480px',
  };

  const completeHandler = (data) => {
    const { address, zonecode } = data;
    setZonecode(zonecode);
    setAddress(address);
  };

  const closeHandler = (state) => {
    if (state === 'FORCE_CLOSE') {
      setIsOpen(false);
    } else if (state === 'COMPLETE_CLOSE') {
      setIsOpen(false);
    }
  };

  const toggleHandler = () => {
    setIsOpen((prevOpenState) => !prevOpenState);
  };

  const inputChangeHandler = (event) => {
    setDetailedAddress(event.target.value);
  };

  return (
    <div>
      <div>
        <strong>address</strong>
      </div>
      <div>
        <div>
          <div>{zonecode}</div>
          <button
            type="button"
            onClick={toggleHandler}
          >
            주소 찾기
          </button>
        </div>
        {isOpen && (
          <div>
            <DaumPostcode
              theme={themeObj}
              style={postCodeStyle}
              onComplete={completeHandler}
              onClose={closeHandler}
            />
          </div>
        )}
        <div>{address}</div>
        <input
          value={detailedAddress}
          onChange={inputChangeHandler}
        />
      </div>
    </div>
  );
};

export default AddressInput;

그리고 스타일과 다른 인풋까지 잘 지정해주면 다음과 같은 폼을 만들 수 있다.
전체 코드는 @eunjios/simple-cart

완성1

완성2


참고 자료

profile
growth

1개의 댓글

comment-user-thumbnail
2024년 7월 15일

감사합니다.

답글 달기
Powered by GraphCDN, the GraphQL CDN