Udemyのオススメ講座はこちら 詳細を見てみる

【React】郵便番号検索APIを使って郵便番号から住所を自動入力する

  • URLをコピーしました!

Reactを使って入力フォームに郵便番号を入力すると非同期で住所が自動入力される、あのユーザー登録画面でよく見るやつをを実装します。(言語はTypeScriptです)

膨大な住所情報は自前で準備するわけではなく、日本郵便が提供する郵便番号検索APIを使用して取得します。

本記事のサンプルコードはCodeSandboxから見れます。

目次

郵便番号から住所を自動入力する方法

サンプル画面

以下の画面で郵便番号を左の入力フォームに前半3桁、右の入力フォームに後半4桁を入力すると、画面の

  • 都道府県
  • 市区町村
  • 町域

の右側にAPIから取得した情報が表示されるようにします。

サンプル画面

タイトルでは「自動入力」と記載していますが、サンプルのため単純に表示するだけにしています。入力フォームに自動入力するためにはinputタグを使うだけなので簡単です。

サンプルコード

この記事で解説するコードはこちらです。

import axios from "axios";
import { ChangeEvent, useState } from "react";

type Zipcode = {
  main: string;
  sub: string;
};
type Address = {
  address1: string;
  address2: string;
  address3: string;
};

export default function App() {
  const [zipcode, setZipcodeMain] = useState<Zipcode>({
    main: "",
    sub: ""
  });
  const [address, setAddress] = useState<Address>({
    address1: "",
    address2: "",
    address3: ""
  });

  const updateZipcodeMain = (e: ChangeEvent<HTMLInputElement>) => {
    setZipcodeMain({ ...zipcode, main: e.target.value });
  };
  const updateZipcodeSub = async (e: ChangeEvent<HTMLInputElement>) => {
    setZipcodeMain({ ...zipcode, sub: e.target.value });
    if (e.target.value.length === 4 && zipcode.main.length === 3) {
      try {
        const res = await axios.get(
          "https://zipcloud.ibsnet.co.jp/api/search",
          {
            params: {
              zipcode: zipcode.main + e.target.value
            }
          }
        );
        if (res.data.results) {
          const result = res.data.results[0];
          setAddress({
            ...address,
            address1: result["address1"],
            address2: result["address2"],
            address3: result["address3"]
          });
        }
      } catch {
        alert("住所の取得に失敗しました。");
      }
    }
  };

  return (
    <div>
      <h2>郵便番号から住所の住所の自動入力</h2>
      <div>
        <span>郵便番号:</span>
        <input type="text" onChange={updateZipcodeMain} value={zipcode.main} />
        <span> - </span>
        <input type="text" onChange={updateZipcodeSub} value={zipcode.sub} />
      </div>
      <div>
        <p>自動入力される住所</p>
        <div>
          <p>都道府県: {address.address1}</p>
          <p>市区町村: {address.address2}</p>
          <p>町域: {address.address3}</p>
        </div>
      </div>
    </div>
  );
}

サンプルコードについて簡単ですが解説します。

郵便番号検索APIへのリクエスト

郵便番号の右の入力フォーム(後半4桁)の入力値が変更されたタイミングで、設定した条件を満たしていたらAPIへのリクエストを行います。

この部分だけを抜粋すると以下のコードです。

  const updateZipcodeSub = async (e: ChangeEvent<HTMLInputElement>) => {
    setZipcodeMain({ ...zipcode, sub: e.target.value });
    if (e.target.value.length === 4 && zipcode.main.length === 3) {
      try {
        const res = await axios.get(
          "https://zipcloud.ibsnet.co.jp/api/search",
          {
            params: {
              zipcode: zipcode.main + e.target.value
            }
          }
        );
        if (res.data.results) {
          const result = res.data.results[0];
          setAddress({
            ...address,
            address1: result["address1"],
            address2: result["address2"],
            address3: result["address3"]
          });
        }
      } catch {
        alert("住所の取得に失敗しました。");
      }
    }
  };

まずは、入力フォームの入力に伴ってuseStateのセット関数でローカルstateを更新します。

setZipcodeMain({ ...zipcode, sub: e.target.value });

郵便番号をオブジェクト型のstateで管理しているので、スプレッド構文を使って更新します。

次にAPIリクエストを行う条件は以下のコードで定義しています。

if (e.target.value.length === 4 && zipcode.main.length === 3) {
  // APIリクエスト
}

文字で書くと以下の条件を満たす場合に郵便番号検索APIにリクエストします。

  • 左の入力フォームの値(既にstateに反映済み)が3桁である
  • 右の入力フォームの入力値が4桁である

APIのリクエストにはAxios(Ajaxライブラリ)を使います。

const res = await axios.get(
  "https://zipcloud.ibsnet.co.jp/api/search",
  {
    params: {
      zipcode: zipcode.main + e.target.value
    }
  }
);

APIのエンドポイントや渡せるパラメータは郵便番号検索APIのサイトに書かれているとおりです。

パラメータの1つであるzipcode7桁の数字 or ハイフン付きで3桁-4桁でも問題ないので今回は7桁の数字にしています。

APIから取得した住所情報の扱い方

APIから返ってきた住所情報のハンドリング部分の実装は以下のコードです。

if (res.data.results) {
  const result = res.data.results[0];
  setAddress({
    ...address,
    address1: result["address1"],
    address2: result["address2"],
    address3: result["address3"]
  });
}

レスポンスには以下の3つのパラメータが含まれます。

プロパティ内容
status正常時は 200。エラー発生時にはエラーコード。
messageエラー発生時に、エラーの内容が返される。
results検索結果。配列で返される。
郵便番号検索APIのレスポンス

詳細は郵便番号検索APIのサイトに記載されているので気になる方はぜひそちらを見ていただけたらと思います。

APIに郵便番号を渡してもその郵便番号が存在しない場合は住所情報も返ってこないので、レスポンスのresultsプロパティの中身がない場合は何も処理をしないようにif文を入れています。

if (res.data.results) {
}

その後は住所情報を管理するローカルstate(address)を検索結果の1つ目の情報で更新することで画面に表示するようにしています。

 const result = res.data.results[0];
  setAddress({
    ...address,
    address1: result["address1"],
    address2: result["address2"],
    address3: result["address3"]
  });

実際に実在する郵便番号を入力すると住所が自動で入力されます。

郵便番号から住所が自動入力されている

CodeSandoxのリンク

冒頭にも載せていますが、実際に入力フォームに入力して住所が自動入力される挙動を試すことができます。

最後に

この記事では必要最低限の機能を実装したものです。

  • 両方の入力フォームに入力した状態で左の入力フォーム(前半の3桁)の入力を変更した時の挙動
  • 住所が自動入力されている状態で右の入力フォーム(後半の4桁)の入力を変更した時に住所情報はリセットする

など実際の運用では考慮することはありますが、その辺は個人でカスタマイズすれば良いかと思います。

React Hooksの基本的な内容はこちらにまとめています。

TypeScript+Next.js(React)+Laravelのハンズオンはこちらから見れます。

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

ブログを開設するなら「SWELL」が絶対オススメ!

この記事を書いた人

大学院(機械工学)→重工業→エンジニア→プロダクトマネージャー(PdM)

神戸グルメのインスタアカウントを運用しています↓
https://www.instagram.com/kobe_gourmet_life/

コメント

コメント一覧 (2件)

  • こんにちはたまたま拝見しましたが
    「日本郵便が提供する郵便番号検索API」
    とありますが、日本郵便が提供するデータを用いたAIBISU社のサービスではないですかね?
    つまり日本郵便公式のサービスというわけではないかと思います。

    サービスの紹介としては良いかと思います。

コメントする

目次