【React Native】簡単なAPI連携のアプリケーションを作成する　①準備編

#はじめに
2021年になってからUdemyで下記の講座で勉強していたため、学習のアウトプットとして記事にします。
[2021年版 React Native, Firebase, Expo でアプリ開発をゼロから始めよう！](https://www.udemy.com/course/react-native-ios-android/)
業務でもスマホアプリ関連に携わっていますが、SwiftやKotlinはちょっと敷居が高そうなのでReact Nativeで開発してみました。
何らかの言語でAPIを叩けるようになる、というまでが一種のゴールかなと思いますので、そこを目標に進めます。
実践的なアプリを作成するというよりは、ハンズオン的にReact Nativeを触ってみるといった趣旨になっていますので、その点はご了承ください。

## 本記事で説明すること

* React Native+Expoの開発環境の構築手順（公式ページの紹介程度）
* アプリの作成手順
* アプリ開発の流れ、実機での確認手順

# 環境
* OS: Windows（macもそんなに変わらないと思います）
* Expo: 4.1.6
* Node.js: v14.15.0

# 実行する予定のAPI
* [郵便番号検索API](http://zipcloud.ibsnet.co.jp/doc/api)
* [OpenWeather API](https://openweathermap.org/api)<br>
上記2つのAPIを用いて郵便番号を入力すると住所と天気を教えてくれるアプリを作成したいです。

# Githubリポジトリ（追記：削除済み）
https://github.com/pbyoshida/postal-app

# 本編
早速本編です。
## 環境構築
[Expo公式ドキュメント](https://docs.expo.io/get-started/installation/)に従っていきましょう。
### すでに導入済みであるとよいもの
* Node.js
* Git
* VSCode
* Expoのサインアップ、ログイン（今回が初回じゃないので必要かわからず。。）
<br>そのほか、記事中ではWindows Power Shell(Windows Terminal)を使用。

### Expo CLIインストール
```powershell
# Expo CLIをグローバルインストール
$ npm install --global expo-cli
```
### Expo Go appの導入
シミュレータで確認することも可能ですが、アプリを動かしている感が好きなので実機で確認することも多いです。下記からインストールしてください。
[Android Play Store](https://play.google.com/store/apps/details?id=host.exp.exponent)
[iOS App Store](https://itunes.com/apps/exponent)

## アプリケーション作成
Expoの導入が終わったらプロジェクトを作成していきましょう。
### プロジェクトの作成
```powershell
# プロジェクトを作成したいフォルダまでcd
$ cd (任意のパス)

# アプリ名はpostal-appとします。
$ expo init postal-app
```
次は上下矢印キーで任意のテンプレートを選びます。
今回テンプレートは"blank"とします。TypeScriptでがっちり書いてみたいですが、自信が無いのでまた今度ということで。

```
? Choose a template: (Use arrow keys)
  ----- Managed workflow -----
> blank                 a minimal app as clean as an empty canvas
  blank (TypeScript)    same as blank but with TypeScript configuration
  tabs (TypeScript)     several example screens and tabs using react-navigation and TypeScript
  ----- Bare workflow -----
  minimal               bare and minimal, just the essentials to get you started
  minimal (TypeScript)  same as minimal but with TypeScript configuration
```
色々とインストールするので、終了するまで待ちます。
終わったら下記のようなメッセージが出ます。

```powershell
✅ Your project is ready!

To run your project, navigate to the directory and run one of the following npm commands.

- cd postal-app
- npm start # you can open iOS, Android, or web from here, or run them directly with the commands below.
- npm run android
- npm run ios # requires an iOS device or macOS for access to an iOS simulator
- npm run web
```
上記の手順に従ってまずはプロジェクトのディレクトリに移動し、まずは動作確認してみましょう。

### 動作確認
```
# プロジェクトディレクトリに移動
$ cd postal-app

# 一応プロジェクト構成を確認しておきます。
$ ls

ディレクトリ: C:\Users\XXX\XXX\XXX\postal-app
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2021/02/14     21:28                .expo-shared
d-----        2021/02/14     21:28                assets
d-----        2021/02/14     21:30                node_modules
-a----        1985/10/26     17:15            118 .gitignore
-a----        1985/10/26     17:15            481 App.js
-a----        2021/02/14     21:28            652 app.json
-a----        1985/10/26     17:15            107 babel.config.js
-a----        2021/02/14     21:30         348813 package-lock.json
-a----        2021/02/14     21:28            549 package.json
```
上記のApp.jsを修正したり、componentやscreenを作成したりします。
続いて作成されたプロジェクトの動作確認です。

```
# アプリケーションの立ち上げ
$ expo start
```
ブラウザが起動し、下記の画面が現れます。
![1初期動作確認.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498497/0261b80c-450c-bf2f-0f76-291945098b45.png)

インストールしたExpo GoでQRコードを読み取ります。
環境差異があるかもしれませんが、"LAN"だとうまくいかず"Tunnel"のほうがうまくいくので、いつもそちらで試しています。
[ここら辺のフォーラム](https://forums.expo.io/t/lan-vs-tunnel-in-expo/11759)を参考にしてください。
さて、"Building JavaScript bundle: finished in XXXms."のようなメッセージと、端末側でJavaScriptのDLをしているメッセージが表示された後、下記画面が表示されます。
<img width="400" alt="2初期動作確認(端末確認).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498497/f7b65268-563a-107c-edc3-16b070730c77.png">

ここで、アプリの本体であるApp.jsを見ましょう。

```javascript:App.js
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Open up App.js to start working on your app!</Text>
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
```
上から大雑把に、"インポートするモジュール群","アプリ本体のfunction","スタイル定義"になっています。

## コードの変更
それではデフォルトから変更を加えていきます。
### js→jsxへの変更、要素の配置
Udemyの講義ではJSではなくJSXで記載していたので、拡張子を変えて（App.js→App.jsx）書き直します。

```jsx:App.jsx
import React, { useState } from 'react';
import { StyleSheet, Text, View, TextInput, Button, Alert } from 'react-native';

export default function App() {
  // 郵便番号を保存しておくstate
  const [postalCode, setPostalCode] = useState('');

  // 送信ボタンを押した時に実行される関数
  function handlePress() {
    // 一旦、入力した番号をAlertで表示する内容としています。
    Alert.alert('入力された内容', postalCode);
  }

  // アプリに描画する内容
  return (
    <View style={styles.container}>
      <Text style={styles.description}>郵便番号を入力してください{"\n"}(ハイフンなし7桁)</Text>
      <TextInput
        value={postalCode}
        style={styles.inputPostalCode}
        onChangeText={(text) =>{
          setPostalCode(text);
        }}
        maxLength={7}
        keyboardType={"numeric"}
        placeholder={"郵便番号"}
      />
      <Button
        title="送信"
        color="#AAAAAA"
        onPress={handlePress}
      />
    </View>
  );
}

// 各要素のスタイル
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  description: {
    fontSize: 18,
    color: '#666666',
    paddingBottom: 10,
  },
  inputPostalCode: {
    textAlignVertical: 'center',
    width: 120,
    fontSize: 24,
    marginBottom: 10,
    borderWidth: 1,
    borderColor: 'rgba(0, 0, 0, 0.2)',
  }
});

```
変更するついでに以下を変更しています。

* ステータスバーを削除
* テキストの文言を変更
* 郵便番号入力のボックスを追加
* 入力した郵便番号をセットするuseStateを追加
* 送信ボタンを追加（ここではただアラート表示するだけ）
* 各要素にスタイルを適用

では上記でいったん動作確認してみましょう。
Androidの場合にはコンソール側でExpoを終了していなければ、Expo Goを再読み込みなどすれば再表示することができます。
<img width="400" alt="3変更後の画面.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289995/d9feb560-a650-e110-42c6-288f100e267e.png">

実際に番号を入力して、送信ボタンを押すと以下のようにアラートが出ます。
<img width="400" alt="4ボタン押下後のアラート.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289995/3984b505-a2cc-c789-46e5-dfa8c593dad9.png">

入力された情報を使ってAPIにリクエストすれば良さそうですね！
続きはまた次回。
（APIの規約とかに引っかからないか怖いです）

2021/2/16　続きを書きました。
→[【React Native】簡単なAPI連携のアプリケーションを作成する　②住所検索の実装](https://qiita.com/kazuki_yoshida/items/cb7df8d51dc0e0c2f8de)

2021/2/20 2個先の続きを書きました。
→[【React Native】簡単なAPI連携のアプリケーションを作成する　③ESLint+Prettierの導入(寄り道)](https://qiita.com/kazuki_yoshida/items/4365b69cf80f1f65692b)

2021/2/21 最終回を書きました。
→[【React Native】簡単なAPI連携のアプリケーションを作成する　④天気情報表示の実装](https://qiita.com/kazuki_yoshida/items/f6f576ec1782b8878e6f)