iimon TECH BLOG

iimonエンジニアが得られた経験や知識を共有して世の中をイイモンにしていくためのブログです

Reactベーシック(React Hooks編):APIデータの取得と表示

初めに


はじめまして!

株式会社iimonでエンジニアをしている澤岻(たくし)です。

普段は、フロントエンド開発等々をしています。

iimonでは今までVueを使ったフロントエンド開発が多かったのですが、

最近Reactでの開発も少しずつ入ってきたので社内の皆さんへの共有がてら、Reactアプリ開発〜ベーシック編〜ということでブログを書いていこうと思います。

今回はReactの特性を知る上でAPIを使ってデータを取得する簡単なアプリを作れればと思います。

Reactとは

実装に入る前に、簡単にReactについて。

Reactは当時のFacebook(現Meta)で開発されたオープンソースJavaScript UIライブラリです。

2013年にリリースされて以降、継続的にアップデートは続いており、最新ver.は18.2.0です。

今では多くのライブラリやフレームワークが登場し、フロントエンド開発の選択肢はかなり広がっています。その中で、人気絶頂とはいかずとも、Reactは今でもフロントエンド開発において一定の人気を保っているかと思います。

また、UIライブラリとして登場したReactですが、Next.jsなどのフレームワークの登場により、UIだけでなく、ウェブアプリケーション開発も可能になりました。

これはVueにも共通しますが、Reactにはコンポーネント志向というものがあります。

コンポーネントは簡単にいえば、1つのUIとロジックをまとめた部品で、コンポーネントは他のコンポーネントで何度でも使うことができます。

propsstateを活用すればかなり自由度が高く汎用性が高いコンポーネントを作成することができます。

とはいえ自分で書いていてもピンときづらい説明。。なので、百聞は一見にしかず!アプリを作りながら実際のコードでイメージを掴んでいければと思います。

導入

インストール

Reactアプリ作成を始めるには大まかに2通りあります。

  1. 必要パッケージを手動でインストール

既存アプリにReactを導入する場合などはこの方法になると思います。

この場合は、webpackやviteなどのモジュールバンドラーやビルドツールの設定も必要になります。

  1. コマンドでお手軽スタート!

npx create-react-app <アプリ名> またはnpm init react-app <アプリ名>

のコマンドを走らせれば必要な設定やファイルなどを用意してくれて、お手軽にスタートできます。

導入に時間がかからないのでまずは試してみたい、という場合にはとても便利ですね!

(npxコマンドはnpm 5.2以上であれば使用できます。)

ということで今回はお手軽コースで進めていきます!

まずは適当なディレクトリでコマンドを走らせてみましょう!

npx create-react-app my-app

ちなみに、TypeScriptで開発したい場合は、

npx create-react-app my-app --template typescript

このように指定してあげれば自動的にやってくれます!(お手軽!)

そうすると、my-appという名前で新しいプロジェクトができているはずです。

README.md
node_modules
package-lock.json
package.json
public
src

my-app内で以下を実行しdevサーバーを起動させます。

npm run start

早速ブラウザでhttp://localhost:3000にアクセスして確認してみましょう!

こんな画面が見れましたか?

ファイルの中身を見てみます。src/App.jsを開いてみましょう。

中身はこのようになっているはずです。

import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

今回はApp.jsを編集し、APIデータをブラウザで表示できるようにしていきます。

その前に、今回は外部APIを使用するため、先にHTTPクライアントライブラリをインストールしておきます。

npm install axios

これで準備万端です。

では早速進めていきましょう!

言語ごとに国の一覧を取得するアプリ

今回はREST Countriesという外部APIを使い、選択した言語が話されている国が一覧で見れるアプリを作ります。今回は仮に英語・中国語・ヘブライ語の3言語のみ選択できるようにします。

1. stateを追加

まずは、必要な関数をimportします。

import { useEffect, useState } from 'react';
import axios from 'axios';

useStateやuseEffectはHooksというもので、Reactコンポーネント内でstateの変数を定義し、その値を更新したりするための関数です。

今回は、言語と国データの2つのstateを追加します。

// 国データ
const [countries, setCountries] = useState([]);
// 言語(初期値:英語)
const [language, setLanguage] = useState('english');

countries、languageはstateであり、setCountries、setLanguageはそこに値をセットするための関数です。

const [state, set関数] = useState(初期値)

ちなみに名前はなんでもいいのですが、set関数はset~とするのがお約束になっています。

2. useEffectを使ってAPIからデータ取得

次は早速APIを使ってデータを取得していきます。

今回は選択した言語をAPIエンドポイントのパスパラメータにセットすることで必要なデータを取得します。以下を追加します。

useEffect(() => {
  axios.get(`https://restcountries.com/v3.1/lang/${language}`)
        .then(res => {
        setCountries(res.data);
      })
        .catch(err => {
            console.log(err);
        });
}, [language]);

useEffectは以下のように2つ引数をとります。

useEffect(setup, dependencies?)

setupはマウント時またはdependencies(依存値)に設定した値の変更を検知された場合に実行される処理です。

今回だと、languageが変更されるたびにAPIを叩く。というロジックになります。

変更を検知させる必要がない場合でも、dependenciesには必ず空配列[] を入れる必要3.があります。

3. セレクトボックスの追加とデータの抽出・表示

今のままではデータを取得しただけで画面では確認できないので、

言語を選択するためのセレクトボックスと、取得したAPIデータから、国名・国旗を一覧で表示できるようにします。

returnの中を以下に差し替えましょう。

return (
    <div className="container">
        <div className="select-wrapper">
          <p>言語を選択</p>
        <select className="select" onChange={(e) => setLanguage(e.target.value)}>
          <option value="english">英語</option>
          <option value="chinese">中国語</option>
          <option value="hebrew">ヘブライ語</option>
        </select>
      </div>
      <div>
        {countries && countries.map((item, i) => (
            <div key={i}>{item.name.common}{item.flag}</div>
           ))}
      </div>
    </div>
);

これはjsxと呼ばれる拡張構文で、jsxでは基本的なHTMLに加え、変数や関数も扱えます。

見た目を簡単にですが整えたいのでsrc/App.cssに以下を追加します。

.container {
  padding: 10rem;
  text-align: center;
}

.select-wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1rem;
}

.select {
  text-align: center;
  padding: 0.5rem;
}

4. ブラウザで確認

ではブラウザを確認してみましょう!

以下のように国名・国旗で一覧が表示されていれば成功です。

最終版App.js

App.js

import axios from 'axios';
import { useEffect, useState } from 'react';
import './App.css';

function App() {
  const [countries, setCoutries] = useState([])
  const [language, setLanguage] = useState('english')

  useEffect(() => {
    axios.get(`https://restcountries.com/v3.1/lang/${language}`)
            .then(res => {
          setCoutries(res.data);
        })
            .catch(err => {
                console.log(err);
            });
  }, [language]);

  return (
    <div className="container">
      <div className="select-wrapper">
        <p>言語を選択</p>
        <select className="select" onChange={(e) => setLanguage(e.target.value)}>
          <option value="english">英語</option>
          <option value="chinese">中国語</option>
          <option value="hebrew">ヘブライ語</option>
        </select>
      </div>
      <div>
        {countries && countries.map((item, i) => (
          <div key={i}>{item.name.common}{item.flag}</div>
        ))}
      </div>
    </div>
  );
}

export default App;

以上。ざっくりReactベーシックでした!

簡単な説明しかしていませんのでぜひドキュメントの方も読んでいただければと思います!

React以外のライブラリやフレームワークも色々触ってみたいですね〜

参考:

https://react.dev/reference/react/useEffect

https://react.dev/reference/react/useState