2018年2月18日
プログラミング
APIから値を取得し表示する 【これからはじめるReact Native】
はじめに
前回は、Expoを使ったReactNativeのアプリ開発についてご紹介しました。
Expoは複雑でカスタマイズしたいようなアプリケーションには向いていませんが、機能が限られているアプリケーションであればとても簡単に開発が可能です。
今回開発するのは、サーバと通信をし、そのデータをリストとして表示するアプリケーションです。
多くのモバイルアプリケーションは、端末上で全てデータを持っているわけではなく、サーバと通信しそのデータを取得し表示するような形となっています。
今回もそういったAPIを使用し、アプリケーション内に取得したデータを表示するものを開発していきます。
データをfetchする
それでは、Expoで新しいプロジェクトを作ります。
App.jsから、APIで値をHTTPリクエストしてみましょう。
こちらのリファレンスにあるように、HTTPリクエストは fetch
で行うことができます。
公式リファレンス Networking
POINT!!
fetchでも十分事足りますが、別のHTTPクライアントライブラリが使われることも多いです。特にシンプルな書き方で使えるaxiosというライブラリが人気です。 また、axiosはVue.jsなどでも使われることが多いです。
では、公式サンプルにもある、https://facebook.github.io/react-native/movies.json
にGETメソッドでアクセスしてみましょう。
これだけです。
fetch('https://facebook.github.io/react-native/movies.json');
値としてはこれらのものを返してくれます。
{
title: "The Basics - Networking",
description: "Your app fetched this from a remote endpoint!",
movies: [
{
title: "Star Wars",
releaseYear: "1977"
},
{
title: "Back to the Future",
releaseYear: "1985"
},
{
title: "The Matrix",
releaseYear: "1999"
},
{
title: "Inception",
releaseYear: "2010"
},
{
title: "Interstellar",
releaseYear: "2014"
}
]
}
このmoviesの値をリストとして展開するアプリケーションができそうですね。
では、このfetchメソッドをどこに置くか考えてみましょう。
アプリケーションを立ち上げたタイミングで値を取得してくれたら、その後のリスト展開が上手くいきそうですね。
さて、このタイミングについては、コンポーネントライフサイクルを理解してから実装する必要があります。
コンポーネントライフサイクル
Reactには、コンポーネントライフサイクルと呼ばれるサイクルがあり、そのタイミングで処理を発動することができます。
具体的には「コンポーネントが作成されたタイミング」、「マウント(画面上に表示)されたタイミング」などがあり、公式リファレンスから簡単に列挙していきます。
componentWillMount()
render()
、つまりマウントの前に呼び出されるメソッドです。
componentDidMount()
マウントが終わった後に呼び出されるメソッドです。
componentWillReceiveProps()
新しいpropsを受け取ると呼び出されるメソッドです。
shouldComponentUpdate()
stateやpropsに更新があった際に、マウントの前に呼び出されるメソッドです。
componentWillUpdate()
コンポーネントの更新マウントされる前に呼び出されるメソッドです。
componentDidUpdate()
コンポーネントの更新マウントされた後に呼び出されるメソッドです。
ちょっと一言
componentWill~系のメソッドはReactのVersion16.4でDeprecate (非推奨)となり、今後廃止されていくようです。16.3 and 16.4 releases
POINT!!
普通のJavaScriptやjQueryを触られたことがある方は、window.onload や$(function(){});、$(document).ready(function(){}); などのイベントを見たことがあるかと思いますが、そちらと近いかもしれません。もちろんjQueryなどは実際のDOMを操作するのに対し、Reactのライフサイクルメソッドでは仮想DOMの生成や内部の状態(state)といった要素が関連する点が大きく異なります。
では、今回のケースの場合はどのメソッドを使うべきでしょうか。
アプリケーションを立ち上げたタイミングでfetchが行われ、その後にrender()
(描画)される必要がある為、componentWillMount()
内で行うのが良さそうですね。
実装を行う
では、実際にコードを書いていきましょう。
Expoのサンプルコードを極力触らず、元の素材も使いながらシンプルに作っていきます。
出来上がるイメージはこちらです。
App.js
import React, { Component } from 'react';
import { Text, View, ScrollView, StyleSheet } from 'react-native';
import { Constants } from 'expo';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-elements'; // 0.18.5
export default class App extends Component {
state = { movies: [] };
componentWillMount() {
return fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) =>
this.setState({
movies: responseJson.movies,
title: responseJson.title
})
)
.catch((error) => {
console.error(error);
});
}
renderMusics() {
return this.state.movies.map(movie =>
<AssetExample key={movie.title} movie={movie} />
);
}
render() {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>
{this.state.title}
</Text>
<ScrollView>
<Card title="Local Modules">
{this.renderMusics()}
</Card>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
color: '#34495e',
},
});
AssetExample.js
import React, { Component } from 'react';
import { Text, View, StyleSheet, Image } from 'react-native';
export default class AssetExample extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>
{this.props.movie.title}
({this.props.movie.releaseYear})
</Text>
<Image style={styles.logo} source={require("../assets/expo.symbol.white.png")}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
alignItems: 'center',
justifyContent: 'center',
},
paragraph: {
margin: 24,
marginTop: 0,
fontSize: 14,
fontWeight: 'bold',
textAlign: 'center',
color: '#34495e',
},
logo: {
backgroundColor: "#056ecf",
height: 128,
width: 128,
}
});
解説
では、App.jsから見ていきましょう。
まず注意するポイントは、ScrollViewです。
import { Text, View, ScrollView, StyleSheet } from 'react-native';
<ScrollView>
<Card title="Local Modules">
{this.renderMusics()}
</Card>
</ScrollView>
ScrollViewですが、こちらはその名前の通りスクロールするViewのコンポーネントです。
こうしたAPIから動的に値を取ってくるものなど、件数が多いとどうしてもViewの場合は表示しきれなくなりがちです。この場合にはスクロールしなければ全体を見ることができず、ScrollViewが必要となります。
そして次のポイントは、fetchで取得した値をstateに保存している処理です。
componentWillMount() {
return fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) =>
this.setState({
movies: responseJson.movies,
title: responseJson.title
})
)
.catch((error) => {
console.error(error);
});
}
この処理でAPIの取得に成功した場合に、stateのmovieとtitleに値を設定しています。
moviesは配列形式の為に、最初に state = { movies: [] };
と初期化している点もポイントです。
renderMusics() {
return this.state.movies.map(movie =>
<AssetExample key={movie.title} movie={movie} />
);
}
<Card title="Local Modules">
{this.renderMusics()}
</Card>
そして、これらでCardの中身にmoviesをmapし、全件を1つずつAssetExampleコンポーネントとしてレンダリングさせています。
その際にmovieの中身も渡していますね。
では、次にAssetExample.jsです。
render() {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>
{this.props.movie.title}
({this.props.movie.releaseYear})
</Text>
<Image style={styles.logo} source={require("../assets/expo.symbol.white.png")}/>
</View>
);
}
}
そして、テキスト部分にpropsに設定したmovieのtitleやreleaseYearを使うことで、APIで取得した値を動的に表示させていることがわかるかと思います。
まとめ
今回はAPIから値を取得し、表示させる処理を実装しました。
またその際にコンポーネントのライフサイクルメソッドも確認しました。
Expoを使っている為、今回実装した内容はすぐにスマホで確認できるはずです。
次回は、レイアウトの整え方などを解説します。
React Nativeのお仕事に関するご相談
Bageleeの運営会社、palanではReact Nativeに関するお仕事のご相談を無料で承っております。
zoomなどのオンラインミーティング、お電話、貴社への訪問、いずれも可能です。
ぜひお気軽にご相談ください。
この記事は
参考になりましたか?
8
2
関連記事
2021年8月30日
React Navigation 6.0のStack Navigatorの大きく変わった箇所の変更点をまとめてみた
2021年1月4日
react-native-svgを使ってReact NativeでSVGを扱う
2019年12月23日
Expo Bare Workflow で Firebase Analytics を設定する
2018年12月6日
【React Native】キーボードで画面が隠れる場合の対処法
2018年7月13日
TypeScriptでReact Native開発をする方法2018年最新版
2018年6月29日
React Navigationのタブナビゲーションをカスタマイズしてみよう!
簡単に自分で作れるWebAR
「palanAR」はオンラインで簡単に作れるWebAR作成ツールです。WebARとはアプリを使用せずに、Webサイト上でARを体験できる新しい技術です。
palanARへpalanでは一緒に働く仲間を募集しています
正社員や業務委託、アルバイトやインターンなど雇用形態にこだわらず、
ベテランの方から業界未経験の方まで様々なかたのお力をお借りしたいと考えております。
運営メンバー
Eishi Saito 総務
SIerやスタートアップ、フリーランスを経て2016年11月にpalan(旧eishis)を設立。 マーケター・ディレクター・エンジニアなど何でも屋。 COBOLからReactまで色んなことやります。
sasakki デザイナー
アメリカの大学を卒業後、日本、シンガポールでデザイナーとして活動。
やまかわたかし デザイナー
フロントエンドデザイナー。デザインからHTML / CSS、JSの実装を担当しています。最近はReactやReact Nativeをよく触っています。
Sayaka Osanai デザイナー
Sketchだいすきプロダクトデザイナー。シンプルだけどちょっとかわいいデザインが得意。 好きな食べものは生ハムとお寿司とカレーです。
はらた エンジニア
サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています
こぼり ともろう エンジニア
サーバーサイドエンジニア。SIerを経て2019年7月に入社。日々学習しながらRuby on Railsを使った開発を行っています。
ささい エンジニア
フロントエンドエンジニア WebGLとReactが強みと言えるように頑張ってます。
Damien
WebAR/VRの企画・開発をやっています。森に住んでいます。
ゲスト bagelee
かっきー
まりな
suzuki
miyagi
ogawa
雑食デザイナー。UI/UXデザインやコーディング、時々フロントエンドやってます。最近はARも。
いわもと
デザイナーをしています。 好きな食べ物はラーメンです。
taishi kobari
フロントエンドの開発を主に担当してます。Blitz.js好きです。
kubota shogo
サーバーサイドエンジニア。Ruby on Railsを使った開発を行いつつ月500kmほど走っています!
nishi tomoya
aihara
グラフィックデザイナーから、フロントエンドエンジニアになりました。最近はWebAR/VRの開発や、Blender、Unityを触っています。モノづくりとワンコが好きです。
nagao
SIerを経てアプリのエンジニアに。xR業界に興味があり、unityを使って開発をしたりしています。
Kainuma
サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています
sugimoto
asama
ando
iwasawa ayane
yoko oshimo
異業界からやってきたデザイナー。palanARのUIをメインに担当してます。これからたくさん吸収していきます!