はじめに
本記事は下記の記事の続編になります。
【React Native】簡単なAPI連携のアプリケーションを作成する ①準備編
実践的なアプリを作成するというよりは、ハンズオン的にReact Nativeを触ってみるといった趣旨になっています。
本記事で説明すること
- axiosの導入・利用
- APIへのリクエスト(住所検索)
Reactで同じようなことをやっている方がいらっしゃいました。
→React、Reduxとaxiosを使って郵便番号から住所を取得する
環境
- axios:0.21.1
今回使用するAPI
Githubリポジトリ(追記:削除済み)
実装
それでは前回のソースから手直しを始めていきます。
axiosの導入
まずはnpmでaxiosをインストールします。
$ npm install axios --save
package.jsonを確認します。
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject"
},
"dependencies": {
"axios": "^0.21.1",
"expo": "~40.0.0",
"expo-status-bar": "~1.0.3",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz",
"react-native-web": "~0.13.12"
},
"devDependencies": {
"@babel/core": "~7.9.0"
},
"private": true
}
11行目にaxiosの記載があり、導入できていそうですね。
ではソースを修正していきます。
import React, { useState } from 'react';
import { StyleSheet, Text, View, TextInput, Button, Alert } from 'react-native';
import axios from 'axios';
// 郵便番号検索APIのURL
const zipcloudURL = 'https://zipcloud.ibsnet.co.jp/api/search';
export default function App() {
// 郵便番号を保存しておくstate
const [postalCode, setPostalCode] = useState('');
const [address, setAddress] = useState('');
// axiosのGETメソッドを使った住所検索
const fetchAddress = async () => {
try {
const response = await axios.get(`${zipcloudURL}?zipcode=${postalCode}`);
const data = response.data;
if ( !data.results ) {
return '該当する住所はありませんでした。'
}
switch (data.status) {
case 200:
// 今回はテストなので、同じ郵便番号で2件以上存在する場合は除きます
return `${data.results[0].address1}${data.results[0].address2}${data.results[0].address3}`;
case 400:
return data.message;
case 500:
return data.message;
}
} catch (error) {
return '検索失敗';
}
}
// 送信ボタンを押した時に実行される関数
async function handlePress() {
// 7桁の数字を正規表現で置きます
const pattern = /^[0-9]{7}$/;
if (pattern.test(postalCode)){
const address = await fetchAddress();
setAddress(address);
} else {
// 想定していない文字列の場合
Alert.alert('正しい郵便番号ではありません', 'もう一度入力してください');
}
}
// アプリに描画する内容
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}
/>
{address.length > 0 && (
<View style={styles.addressContainer}>
<View style={styles.addressLabel}>
<Text style={styles.addressLabelText}>住所</Text>
</View>
<View style={styles.address}>
<Text style={styles.addressText}>{address}</Text>
</View>
</View>
)}
</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,
paddingLeft: 5,
borderWidth: 1,
borderColor: 'rgba(0, 0, 0, 0.2)',
},
addressContainer: {
paddingVertical: 10,
width: 280,
},
addressLabel: {
paddingBottom: 10,
},
addressLabelText: {
fontSize: 18,
color: '#666666',
},
address: {
paddingLeft: 5,
},
addressText: {
fontSize: 16,
color: '#000000',
},
});
結構ソースが長くなってしまっています。今回はQiita用に長めに書いているのもありますが、
どの程度分割すべきかあまり分かっていない節はあります。
中身の解説
fetchAddressメソッドがaxiosを用いてAPIにリスエストする処理です。
通常は連結した住所の文字列をreturnします。
検索結果が0件の場合、data.resultsがnullになるのでその場合は0件のメッセージをreturnします。
また、送信ボタンを押したときの処理として、7桁の数字かを確認し、
変な文字列を入力していた場合にはアラートでユーザーに通知するようにしています。
レンダリングする処理についてはaddressの長さで判断し、検索後は住所を表示します。
動作確認
- 初期画面
- 正常に検索結果を表示
- 数字以外の文字列の場合
- 検索結果が0件の場合
次回予告
あと1,2回で完結予定です。
ただ、次回はちょっと寄り道をしてESLint+Prettierの導入をしようと思います。
(今回ソースを書いててなかなか不便だったのと、備忘を兼ねて。。)
2021/2/20 続きを書きました。
→【React Native】簡単なAPI連携のアプリケーションを作成する ③ESLint+Prettierの導入(寄り道)
2021/2/21 最終回を書きました。
→【React Native】簡単なAPI連携のアプリケーションを作成する ④天気情報表示の実装