uwu

プログラミングの備忘録を書いています。誰かの為になれば幸いです

GeoDB Cities APIを使ってReactで都市の入力候補機能を実装する

GeoDB cities APIとは?


都市データベースです。都市、地域、国のデータを公開します。
今回はこちらのAPIを使って都市の入力候補機能を実装します。

作ったもの


こんな感じのシンプルな検索フォームです。





文字を入力するとそれに続く都市が出てきます。





早速やっていきましょう!


API keyの取得


1. rapid API hubでアカウント作成


API Hub - Free Public & Open Rest APIs | RapidAPI


2. search for APIsで『GeoDB Cities』と検索


3. 無料プランをsubscribeします。


4. Endpoints→javaScript→fetchを選んでAPI keyを確認します。
copy codesをクリックして自分がわかりやすい場所にコピペしておきます。


② Reactアプリの準備

Create-react-appを使ってプロジェクトを作成します。


npx create-react-app react-weather-app
cd react-weather-app

今回は検索フォームにreact-select-async-paginateを使用します。
執筆時(2022年7月)時点では、create-react-appで作ったReactのバージョンが18で、
react-select-async-paginateが18に完全対応していないので--forceオプションをつけてインストールしています。


npm i react-select-async-paginate --force

問題なく起動できるか確認します。



npm run start
③ コーディング

api.jsファイルを作成して先ほど確認したAPI keyとAPI URLをexportするようにします。



export const geoApioptions = {
  method: 'GET',
  headers: {
    'X-RapidAPI-Key': '自分のAPIキー',
    'X-RapidAPI-Host': 'wft-geo-db.p.rapidapi.com',
  },
};

export const GEO_API_URL = 'https://wft-geo-db.p.rapidapi.com/v1/geo';

メインのコードです。search.jsファイルを作成して下記を追加


import { useState } from 'react';
import { AsyncPaginate } from 'react-select-async-paginate';

import { GEO_API_URL, geoApioptions } from './api';

const Search = ({ onSearchChange }) => {
  const { search, setSearch } = useState(null);

  const handleOnChange = (searchData) => {
    setSearch(searchData);
    onSearchChange(searchData);
  };

  const loadOptions = (inputValue) => {
    return fetch(
      `${GEO_API_URL}/cities?minPopulation=1000000&namePrefix=${inputValue}`,
      geoApioptions
    )
      .then((response) => response.json())
      .then((response) => {
        return {
          options: response.data.map((city) => {
            return {
              value: `${city.latitude} ${city.longitude}`,
              label: `${city.name}, ${city.countryCode}`,
            };
          }),
        };
      })
      .catch((err) => console.error(err));
  };

  return (
    <AsyncPaginate
      placeholder='Search for city'
      debounceTimeout={600}
      value={search}
      onChange={handleOnChange}
      loadOptions={loadOptions}
    />
  );
};

export default Search;
      `${GEO_API_URL}/cities?minPopulation=1000000&namePrefix=${inputValue}`,
      geoApioptions

citiesというのは都市の情報を持ってくるためのもの、
minPopulation=1000000
これは人口100万人以上の都市のみを表示させる為のオプションです。
namePrefix=${inputValue}で入力された文字を渡しています。



App.jsを下記に変更


import './App.css';
import Search from './search';

function App() {
  const handleOnSearchChange = () => {
    console.log();
  };
  return (
    <div className='container'>
      <Search onSearchChange={handleOnSearchChange} />
    </div>
  );
}

export default App;

これでできました。