[최종 프로젝트 - React with typescript] 카카오 주소 검색 API, 버튼 활성화/비활성화

Habin Lee·2024년 1월 18일
0

주소 검색 API

  • 직거래 장소를 등록해야하는 폼이 있어 카카오에서 제공하는 주소 검색 API를 사용하기로 했다. 다른 API는 잘 보이지 않을 정도로 react-daum-postcode를 이용하는 사람이 많았고 관련 자료도 많아서 생각보다 쉽게 사용해볼 수 있었다.

1. react-daum-postcode 설치하기(yarn)

yarn add react-daum-postcode

2. 주소 검색 API 사용하기

(1) form 만들기

  • 먼저 주소 검색을 할 수 있는 form과 주소가 보여질 input창을 만들어준다.
  • 주소 검색 form은 컴포넌트를 따로 빼주도록 하자.

ProductsWriteForm.tsx

  • textRadioValue state에 주소에 대한 기본 값과 type이 없어서 먼저 지정해준다.
type TextRadioValueType = {
  title: string,
  contents: string,
  price: number,
  count: number, 
  exchange_product: string,
  tags: string[],
  shipping_cost: string,
  deal_type: string,
  quality: string,
  changable: string,
  address: string,
  detailAddress: string
}

const productsPostsTextInit: TextRadioValueType = {
  title: "",
  contents: "",
  price: 0,
  count: 0, 
  exchange_product: "",
  tags: [],
  shipping_cost: "",
  deal_type: "",
  quality: "",
  changable: "",
  address: "",
  detailAddress: ""
}
  • form 작성 후 input value를 관리하는 state(textRadioValue)를 props로 내려준다.
  • textRadioValue state는 이 게시글을 보면 알 수 있다.
  • 주소 검색을 이용하여 보여주기만 하는 input(address)에는 readOnly 속성을 넣어주고 상세주소는 직접 적을 수 있도록 input을 따로 만든 후 input value에 연결 시켜준다.
const ProductsWriteForm = () => {
  
...(중략)

  return (
    <div>
      <h2>직거래 지역</h2>
      <AddressBtn 
        textRadioValue={textRadioValue} 
        setTextRadioValue={setTextRadioValue} />
      <input readOnly type='text' name='address' 
        value={textRadioValue.address}
        onChange={handleOnChangeTextRadioValue} 
        placeholder='주소검색을 이용해주세요.' />
      <input type='text' name='detailAddress' 
        value={textRadioValue.detailAddress} 
        onChange={handleOnChangeTextRadioValue} 
        placeholder='상세주소를 입력해주세요.' />
    </div>
  )
};

AddressBtn.tsx

  • 이제 주소 검색 버튼을 만들어 줄 차례다.
  • 주소 검색 컴포넌트를 새로 만들고 카카오 주소 검색 API 공식 문서에 코드를 그대로 가져온 후 버튼에 onClick으로 연결해준다.
  • 나는 팝업형식을 사용하기 위해 useDaumPostcodePopup을 사용하였다.(import 필수)
  • 주소 검색 API를 사용하기 위해 scriptUrl도 type을 정해준다.

* 전체코드

import { useDaumPostcodePopup } from 'react-daum-postcode';

interface Props {
  scriptUrl?: string,
  textRadioValue: TextRadioValueType,
  setTextRadioValue: React.Dispatch<React.SetStateAction<TextRadioValueType>>
}

const AddressBtn = ({scriptUrl, textRadioValue, setTextRadioValue}: Props) => {

  const open = useDaumPostcodePopup(scriptUrl);

  const handleComplete = (data: any) => {
    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})` : "";
    }

    // 입력된 주소 값(fullAddress)을 상태 값의 address에 바꿔 넣기
    setTextRadioValue(prev => ({ ...prev, address: fullAddress }));
  };

  const handleOnClickAddressBtn = (e: React.MouseEvent<HTMLButtonElement>) => {
    open({ onComplete: handleComplete });
    e.preventDefault();
  };

  return (
    <div>
      <button onClick={handleOnClickAddressBtn}>주소 검색</button>
    </div>
  );
}

export default AddressBtn
  • 공식 문서가 잘 되어있어서 정말 그대로 가져와 타입만 따로 지정해줬더니 바로 사용이 가능했다.
  • 이렇게 귀여운 주소 검색 버튼과 input이 생기고, 버튼을 눌러주니 팝업도 잘 나타난다.

  • input 영역이 작아 뒷 부분은 안보이지만 주소 검색 역시 잘 되는 것을 확인할 수 있다.
    (빠른 css 작업 요망..)

버튼 활성화 비활성화

  • 나는 사용자가 거래방식에서 직거래를 클릭했을 때만 주소를 적을 수 있도록 하고 싶었기 때문에 다른 버튼을 선택하면 비활성화가 되도록 만들기로 했다.

button의 disabled 속성 사용하기

  • 버튼에 disabled 속성을 넣고 그 안에 조건을 적어주었더니 활성화/비활성화를 적용하는 것은 아주 쉬웠다.
<div>
  <h2>직거래 지역</h2>
  <AddressBtn 
    textRadioValue={textRadioValue} 
    setTextRadioValue={setTextRadioValue} />
  <input readOnly type='text' name='address' 
    value={textRadioValue.address}
    disabled={textRadioValue.deal_type === '택배' || textRadioValue.deal_type === '협의 후 결정'}
    onChange={handleOnChangeTextRadioValue} 
    placeholder='주소검색을 이용해주세요.' />
  <input type='text' name='detailAddress' 
    value={textRadioValue.detailAddress}
    disabled={textRadioValue.deal_type === '택배' || textRadioValue.deal_type === '협의 후 결정'}
    onChange={handleOnChangeTextRadioValue} 
    placeholder='상세주소를 입력해주세요.' />
</div>
  • 이렇게 하면 직거래 외 선택을 했을 때는 비활성화가 되는 것을 확인할 수 있다.

업로드중..

참고

0개의 댓글