2018年2月18日

プログラミング

APIから値を取得し表示する 【これからはじめるReact Native】

目次

  1. はじめに
  2. データをfetchする
  3. コンポーネントライフサイクル
  4. 実装を行う
  5. まとめ

はじめに

前回は、Expoを使ったReactNativeのアプリ開発についてご紹介しました。

Expoでアプリを作る 【これからはじめるReact Native】

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

AUTHOR

eishis

Eishi Saito 総務

SIerやスタートアップ、フリーランスを経て2016年11月にpalan(旧eishis)を設立。 マーケター・ディレクター・エンジニアなど何でも屋。 COBOLからReactまで色んなことやります。

アプリでもっと便利に!気になる記事をチェック!

記事のお気に入り登録やランキングが表示される昨日に対応!毎日の情報収集や調べ物にもっと身近なメディアになりました。

簡単に自分で作れるWebAR

「palanAR」はオンラインで簡単に作れるWebAR作成ツールです。WebARとはアプリを使用せずに、Webサイト上でARを体験できる新しい技術です。

palanARへ
palanar

palanはWebARの開発を
行っています

弊社では企画からサービスの公開終了まで一緒に関わらせていただきます。 企画からシステム開発、3DCG、デザインまで一貫して承ります。

webar_waterpark

palanでは一緒に働く仲間を募集しています

正社員や業務委託、アルバイトやインターンなど雇用形態にこだわらず、
ベテランの方から業界未経験の方まで様々なかたのお力をお借りしたいと考えております。

話を聞いてみたい

運営メンバー

eishis

Eishi Saito 総務

SIerやスタートアップ、フリーランスを経て2016年11月にpalan(旧eishis)を設立。 マーケター・ディレクター・エンジニアなど何でも屋。 COBOLからReactまで色んなことやります。

sasakki デザイナー

アメリカの大学を卒業後、日本、シンガポールでデザイナーとして活動。

yamakawa

やまかわたかし デザイナー

フロントエンドデザイナー。デザインからHTML / CSS、JSの実装を担当しています。最近はReactやReact Nativeをよく触っています。

Sayaka Osanai デザイナー

Sketchだいすきプロダクトデザイナー。シンプルだけどちょっとかわいいデザインが得意。 好きな食べものは生ハムとお寿司とカレーです。

はらた

はらた エンジニア

サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています

kobori

こぼり ともろう エンジニア

サーバーサイドエンジニア。SIerを経て2019年7月に入社。日々学習しながらRuby on Railsを使った開発を行っています。

sasai

ささい エンジニア

フロントエンドエンジニア WebGLとReactが強みと言えるように頑張ってます。

damien

Damien

WebAR/VRの企画・開発をやっています。森に住んでいます。

ゲスト bagelee

ゲスト bagelee

かっきー

かっきー

まりな

まりな

suzuki

suzuki

miyagi

ogawa

ogawa

雑食デザイナー。UI/UXデザインやコーディング、時々フロントエンドやってます。最近はARも。

いわもと

いわもと

デザイナーをしています。 好きな食べ物はラーメンです。

kobari

taishi kobari

フロントエンドの開発を主に担当してます。Blitz.js好きです。

shogokubota

kubota shogo

サーバーサイドエンジニア。Ruby on Railsを使った開発を行いつつ月500kmほど走っています!

nishi tomoya

aihara

aihara

グラフィックデザイナーから、フロントエンドエンジニアになりました。最近はWebAR/VRの開発や、Blender、Unityを触っています。モノづくりとワンコが好きです。

nagao

SIerを経てアプリのエンジニアに。xR業界に興味があり、unityを使って開発をしたりしています。

kainuma

Kainuma

サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています

sugimoto

sugimoto

asama

ando

iwasawa ayane

oshimo

yoko oshimo

異業界からやってきたデザイナー。palanARのUIをメインに担当してます。これからたくさん吸収していきます!

CONTACT PAGE TOP