【両OS対応】 React Nativeで爆速プロトタイプアプリを作ろう 1/3 【ウェルカム画面編】
※※※※※
本記事は2018年5月に執筆されました.当時の React Native の環境から変わっている部分もありますので,2020年5月より記事の値段を大幅値下げすると同時に,記事更新や質問等のサポートの対象外とさせて頂きます.
m(_ _ )m
1/3 【ウェルカム画面編】:799円 → 199円
2/3 【ホームタブ編】:899円 → 299円
3/3 【プラスボタン編】:999円 → 399円
※※※※※
1. ウェルカム画面編 ← 今ココ
2. ホームタブ編
3. プラスボタン編
note.muの中の方からもコメント頂けました!ありがとうございます!
↑このシリーズの最終完成形
↑この記事での目標
この記事で得れる物
・上図のスマホアプリが作れるようになる
・React Nativeの流れを図で直感的にわかる
・なぜこのようにプログラミングをしたのかまでわかる
この記事の対象者
・アプリ開発経験そんなない方
・Web系開発経験そんなない方
・でもまあほんのちょっとプログラミングかじった事ある方
大丈夫です、僕も当時こんな感じでした。Swift(iOS用プログラミング言語)もKotlin(Android用プログラミング言語)も知らなければ、よく聞くjQueryすら触った事ないほどJavaScript(Web系プログラミング言語)に対する知識もありませんでした。それでも習得できたので大丈夫です。筆者が水先案内人として読者の方々を、「後は自分でググればいける」というレベルまで引き上げます。また、Windowsでも開発できますが、本記事ではMacで作る事を想定してます。
React Nativeとは?
本来ならiOSアプリとAndroidアプリは別言語で書かなければいけなかったのですが、2015年くらいにiOSとAndroidの両アプリを同時に書けちゃう画期的なプログラミング言語をFacebook社が開発しました。それがReact Nativeです(正確にはReact Nativeはプログラミング言語ではなくてライブラリというやつで、実際はJavaScriptって言語で書きます)。
処理速度も速く、高く評価されており、FacebookやInstagramは元よりAirbnbなどの超有名アプリもReact Nativeにどんどん乗り換えています。日本製アプリで言うとメルカリやProgateもReact Nativeだそうです。理由は一言で言うと、開発スピードが速いからです。トレンドの移り変わりが激しい現代のITベンチャーにおいてこれほど嬉しい利点は他にないでしょう。
この記事の目的は?
と、つまり激アツなプログラミング言語なのですがいかんせん日本語のまとまった情報が少なく、僕自身学ぶ際に非常に苦労したのでこのチュートリアル記事を執筆することにしました。
「起業したい!良いアイデアを思いついた!でもアプリ作ったことないし、だからといって周りにエンジニアもいない……よしここは一丁自分でプロトタイプを作ってみよう。Instagramもメルカリも最初はプログラミング未経験から始めたんだし!」
……と意気込んで調べてみるものの、出てくるQiitaなどの記事はどれも既にある程度の知識を持ってる前提で話が進んでることがしばしば。いやソースコードだけ貼られてもわかんねえし、みたいな。
そこでこのReact Nativeを初学者でも簡単に学べれるようになれば、iOS/Androidの両アプリを一気に作れちゃうし、爆速で手元にある実機で動作確認できるし、リリース後はApp Storeの審査を待たずに細かな修正をできるし……と言ったベンチャーにとって非常に有利になる武器を持った状態からスタートできます。そして何より僕自身「アプリってこんな簡単に作れるんだ!」と感動したのでその感動をもっと広めたく執筆しました。
SwiftもKotlinもJavaScriptも知らなかった筆者がReact Nativeを学ぶ際に実際に引っかかった点を主に、「もっとこうやって教えてくれたら良かったのに」という視点から超初心者(かつての自分)向けにスクショ豊富で書いてます。わかりやすさを優先しているためざっくりとした説明が多く、本当の意味での正確性には欠けているかもしれません。ただ読み進めてコード書き写してくだけでそれなりのアプリが作れるようになる、そんな記事にしたいと思います。実際にあなたのスマホ上で作ったアプリを動かしますので、スマホからではなくPCからの閲覧推奨です。
作るアプリは"旅行記アプリ"です。過去に自分が行った国と日付を入力し、その時の思い出の写真とその旅行の3段階評価を付けて保存していく、というアプリです(Trip + record = Treco)。まあ使い道があるかどうかはいいとして(笑)、このアプリにはよくある要素の
・真ん中が `+` プラスボタンになってるタブ構成 & 画面遷移
・日付等を選ぶプルダウンメニュー
・地図や画像の配置
などが多く積み込まれています。あとはこれらの基礎要素を応用して組み替えたりしていけば、大体頭の中で想像しているアプリを実装できるようになりますし、何よりこのチュートリアルシリーズを読み終わってる頃には、自力で検索して必要な情報だけを探せれるようになっています。
本記事では以上のような旅行記アプリの、初回起動時に現れるウェルカム画面までを実装するチュートリアルです。
1. ウェルカム画面編 ← 今ココ
2. ホームタブ編
3. プラスボタン編
開発環境を整えよう
手始めとしてMacでiOSアプリを開発することを想定して開発環境を構築します。まずはMacのApp StoreからXcodeをダウンロードします。容量大きいんで結構時間かかります。
Xcodeのインストールが終わったら、少しXcodeの設定を確認します。画面左上のメニューから`Xcode` → `Preferences`に行き、
`Locations`タブの`Command Line Tools`で一番最新のバージョンのやつを選択して下さい。
次にReact Nativeを開発するための下準備をしましょう。下準備に必要なもの達をインストールするためには、先にHomebrewというやつをインストールしなければいけません…。Macからターミナルを開くと、
自分のMacの名前の横にドルマーク`$`があって、ドルマーク`$`の右側から文字が入力できるようになります。そこの領域に、
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
上記のドルマーク`$`以降(/usr/bin/ruby~~の部分)をコピペしてエンターを押すと、何やら聞かれるので再度エンターを押して待ちます。Macのパスワード入力を求められたら素直にパスワードを入力して下さい、怪しいものじゃありません笑。
上記のHomebrewのインストールが終わったら`$ brew`コマンドが使えるようになるので、その`$ brew`を使ってReact Nativeの下準備をします。
$ brew install node
もちろんここでもドルマーク`$`以降(brew~~の部分)だけをコピペしてエンター。上記が終わったら、
$ npm install npm@latest -g
をして下さい(これは`$ npm`自身を最新ver. にアプデするコマンドです)。最後に、
$ brew install watchman
をして、下準備は完了です。そしたらReact Nativeの開発支援ツールであるExpoをインストールします。このExpoのおかげでめちゃくちゃ開発が楽チンになっているのです。(注:Expo以外にもReact Nativeを始める手段は色々ありますが、筆者はExpo推しです。また以前紹介していたExpo XDEはもうサポート終了してしまったそうです)
$ npm install expo-cli --global
ダウンロードを待っている間に、こちらでExpoアカウントを作っておきましょう。
最後に実際にソースコードを書くエディターソフトですが、極端な話メモ帳ソフトでも何でも良いですが、僕はAtomをお勧めします。こちらからダウンロードしましょう。
はい、お疲れ様でした。ここまででやーっと環境構築が終わりました笑。
実際にアプリを作ってみよう
ではここから実際にプログラミングを始めましょう。ターミナルで
$ expo init react-native-bakusoku
と打って新規プロジェクト`react-native-bakusoku`を作成します。
すると`blank`か`tabs`を聞かれるので、真っ新な状態から始められる`blank`の方を選択してエンターキーで決定します。
プロジェクト名とは別に、ホームスクリーン上でのアプリ名を聞かれるので好きななまえを入れます。
ここは`n`と打ってエンターキー。すると色々とダウンロードが始まるので待ちます。
これが表示されたら終了です。この時点で`react-native-bakusoku`という名前のフォルダが作られています。
それではAtomで先ほど作成したプロジェクト`react-native-bakusoku`を早速開きましょう。
そして既に勝手にいくつかのファイルが自動で作られており、その中の`App.js`の中身をのぞいてみます。
なにやらもう既に色々書かれてますね。ここがExpo XDEの便利な点で、私達の代わりに上記のようなプログラミング雛形を勝手に作ってくれます。ここでTextタグ
<Text> ~~ </Text>
に囲まれた部分の文章を変えてみましょう。
<Text>Open up App.js to start working on your app!</Text>
↓
<Text>Hello React Native!</Text>
ちなみに、<〇〇>と</〇〇>をセットで〇〇タグと呼びます。
<〇〇>で開けて</〇〇>で閉じるまで、ずっと〇〇タグの効果が適用されます。
<〇〇>←ここから〇〇の効果が始まり 〜 〇〇の効果はここまで→</〇〇>
んでTextタグは「タグ内の文書をアプリ画面に映し出す」という効果を持っているので、
<Text>Hello React Native!</Text>
と書けばアプリ画面に"Hello React Native!"って出る、ということです。では`App.js`を保存して、早速アプリを起動して試してみましょう。Atomからターミナルに戻って、
$ expo start
と打ちます。するとブラウザ上で`Expo Developer Tools`というものが立ち上がります。そこで`Run on iOS Simulator`をクリック。
するとiOSシミュレータが起動します(結構時間かかります)。このiOSシミュレータを使いたいがために最初にXcodeをインストールしたのです。
初回は恐らく上図のように聞かれるので`Open`をクリック。
無事アプリが起動しました!ちゃんとTextタグの変更が反映されてます!
もしここでiPhone Xのシミュレータが起動しちゃった人は、iPhone 8に変更することもできます(本記事では以降iPhone 8でやっていきます)。
`Simulator`→`Hardware`→`Device`→`iOS 〇〇.〇`→`iPhone 8`をクリック。すると、iPhone X(一台目)とiPhone 8(二台目)の二つのシミュレータが同時に動いている状態になり、その状態でiOSシミュレータを閉じます。
iOSシミュレータが二つとも一気に閉じられるので、そしたら再度Expo Developer Toolsにて`Run on iOS Simulator`をクリックすると今度は最初からiPhone 8シミュレータが起動します!
最後に起動されたiOSシミュレータを次回も最初に開くので、逆にiPhone Xシミュレータに戻したくなった時は今の手順とは逆に、「iPhone 8の後にiPhone Xを開く」→「2つとも同時に閉じる」→「再度Expo XDEからiOSシミュレータを起動する」でOKです。
JavaScriptの文法エラーチェック機能を追加しよう
さて、ここからアプリをガンガン作って行くのですがその前に、今後ずっとスーパー役に立つ文法エラーチェック機能を追加しておきましょう。この機能を追加する事でエラーを起こす回数がグッと減ります。
Atomを起動して`Atom` → `Preferences`とクリックし、
画面左側の`Install`タブへ行ってそこで`linter-eslint`と検索して下さい。
検索して出てきた`linter-eslint`(ロケットアイコン)と`linter`(ピカチュウアイコン)の両方をインストールします。
もし先に`linter-eslint`を先にインストールすると、「`linter-eslint`は`linter`も必要としますけど、そっちも入れて良いっすか?」って言う青いメッセージが出てきます。まあ、青い方の`Yes`選んでもピカチュウアイコンの方の`Install`押しても一緒なんでどちらでも大丈夫です。
そしたら今度はターミナルを起動し、`react-native-bakusoku`のあるフォルダまで`$ cd`コマンドで移動します。
$ cd ~/先ほど/Expo XDEで/指定した保存場所/react-native-bakusoku
そこで、
$ ls
と打つと今どんなファイルが存在してるか見れるのですが、恐らく大体こんな感じになってるかと思います。
そこで下記の`$ npm`コマンドを実行します。
$ npm install --save-dev eslint-config-rallycoding
何やらダウンロードが始まります。終わったら念のため再度、
$ npm install
を実行して下さい。今度は`--save-dev eslint-config-rallycoding`は要りません。
最後に`react-native-bakusoku`フォルダ内に一個新しく設定ファイルを追加しましょう。Atomから`react-native-bakusoku`を右クリック → `New File`を選択し、
`.eslintrc`というファイル名を付けます。先頭にドット`.`を付け忘れないで下さい。
そしてその`.eslintrc`に下記をコピペします↓。
{
"extends": "rallycoding",
"rules": {
"arrow-body-style": 0
}
}
はい、今度こそ本当の意味で環境構築が終わりました笑。
横スクロールのスライドページを作ってみよう
ではここからどんどん作り込んでいきましょう!アプリ初回起動時に「このアプリの使い方」的な感じでよく出てくる、横スクロール3ページ分くらいのウェルカム画面(正式な名前わからない泣)を手始めに作ってみましょう。この記事の冒頭にもありましたGIFが完成図です↓。
ヌルッとした感じで左右にスクロールでき、各ページにはステップ別の指示が書いてあり、最後のページには「さあ、始めよう!」なんて書かれたボタンが配置されてるアレです。
早速Atomに戻り、`App.js`にブァーってコードを書き始めるのかと思いきや、新しく別のファイルを作ってそこに書きます。どの言語でもそうですがプログラミングは一箇所に全部書くとごちゃごちゃになるし、どっからどこまでが同一機能なのかわかりづらくなるため、各機能ごとに独立して新たなファイルに書きます。んでそれら各ファイルを最後に一箇所の`App.js`に集約するっていう流れです。そうすることによって「A機能を修正したい!」となったら`A.js`ってファイルだけ弄ればいいし、「B機能がぶっ壊れた!」となれば`B.js`ってファイルだけ直せばよくなります(基本的に)。
ということで、一旦`screens`というフォルダを作って、その中に新規ファイル`WelcomeScreen.js`を新たに作りましょう!
`App.js`には雛形を勝手に作ってくれたExpoですが、私達が新規に作ったファイルには雛形を自動では書いてくれません。なので真っ新な`WelcomeScreen.js`にReact Nativeの以下の雛形を自分達で書いていきます。
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
class WelcomeScreen extends React.Component {
render() {
return (
);
}
}
export default WelcomeScreen;
まずはおまじないだと思って、↑上記を(コピペではなくキーボードで)書き写してください。
解説をすると、
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
はReact Nativeを使用するために絶対必要で、これ書かないと始まりません。
class WelcomeScreen extends React.Component {
}
上記は`WelcomeScreen`という名のコンポーネントを作りますよ、という意味です。コンポーネントとは、一つのまとまった機能を表す部品みたいなもので、上述の通り基本的に1機能1ファイルなので1ファイル1コンポーネントとなります。
class WelcomeScreen extends React.Component {
render() {
return (
);
}
}
んでコンポーネントは必ず`render()`という名の関数を持っており、その`render()`関数が返す`return ();`の中身がアプリ画面上に描画されます。関数とは、何か入れると中でゴニョゴニョ加工されて姿形を変えて何かしらが返ってくるモノのことを言います。100円玉入れると→中でなんか処理されて→ジュースがボトンッて出てくる自販機と理屈は一緒です笑。入力が入る→中で何かしら処理される→出力が返ってくるの3ステップです。コンポーネントはまず最初に(和訳すると"描画する"という意味の)`render()`関数を実行し、→中でなんか処理したりしなかったりして、→`return ();`の中に書かれたことが返ってくる→アプリ画面上に描画される……という流れです。つまり`render()`の中の`return ();`内に書く内容にほぼ全てがかかってます。
※ちなみに`render()`の括弧前にスペースは無いのに、`return ();`のカッコ前にスペースが1つ有るのは、それで合ってます。ご心配なく。
export default WelcomeScreen;
最後のこの一文は、後にこの`WelcomeScreen`コンポーネントを`App.js`に集約させるときに必要な文章です。`App.js`から外部ファイル(≒外部コンポーネント)を取り入れることをインポートすると言いますが、そのためには`WelcomeScreen`がエクスポートする(取り出す)ことを許可しなければいけません。こういうとこいちいち書かないとすぐエラーなっちゃうのがプログラミングの頭固いとこですね汗。
それでは早速重要な`return ();`の中身を書いていきます。React Nativeは便利なもので、スクロール機能を実現するためのScrollViewタグ(`S`と`V`が大文字なので注意)というものが既に用意されており、我々はその使い方に従って書けばいいだけで、自前で一から作成する必要はありません。
class WelcomeScreen extends React.Component {
render() {
return (
<ScrollView>
</ScrollView>
);
}
}
<〇〇>で開いたタグはちゃんと</〇〇>で閉じるのを忘れないでください!それからScrollViewタグ自体も`WelcomeScreen.js`にとって外部である`react-native`からインポートしておかなければ、エラーなってしまいます。
import { StyleSheet, Text, View, ScrollView } from 'react-native';
なので↑上記のように波括弧`{ }`の中に`ScrollView`を追加して下さい(`S`と`V`が大文字なので注意)。
この状態で既に縦スクロールできる状態になってますが、このままでは希望の動作から大分遠いので、
・`horizontal`…スクロール方向を横にする
・`pagingEnabled`…ヌルッ→ピタって感じで1ページごと止まるようにする
・`flex: 1`…描画エリアをスマホ画面上一杯を占有するようにする
の3オプションをScrollViewタグに追加します。こういった追加オプションは下記↓のように開始タグの中に書くことによって反映され、一応プロパティって名前が付いてます。
<ScrollView
horizontal // horizontal={true}でも可
pagingEnabled // pagingEnabled={true}でも可
style={{ flex: 1 }}
>
</ScrollView>
ここで疑問となるのが、なぜ波括弧`{ }`が一重の時と二重の時があるのかということですね。まず一重にしろ二重にしろ、一番外側の波括弧`{ }`は、「今からこの波括弧の中にJavaScriptを書きますよ〜」という合図です。
ん、待てよ…ってことは<〇〇>タグとかはJavaScriptじゃないの…?
正解です笑。ここがまたReact Nativeをややこしくする点なんですけど、React NativeはJavaScriptだけでなくHTML風のやつ(正式名称はJSX)も書けるというルールなんです。そしてボタンの配置位置とかは全てこのHTML風のやつ、つまり<〇〇>タグを使って記述します。しかしそのHTML風のやつの中に更にまたJavaScript書きたくなる時があって(ややこしい汗)、その時は波括弧`{ }`で囲ってからJavaScriptを書く、というルールです。
じゃあ二重の波括弧`{ }`はどうなっているかと言うと、HTML風のやつにとって波括弧`{ }`は「今からこの波括弧の中にJavaScriptを書きますよ〜」という合図でしたが、JavaScriptにとって波括弧`{ }`はまた別の意味を指します。それは、JavaScriptオブジェクトというものです。まあ名前なんてどうでもいいんですが、`{ flex: 1 }`を例にすると、
「`flex`という項目の値が → `1`である」
という意味の塊となります。これを応用すると`{ aaa: 1, bbb: 2, ccc: 3 }`は、
「`aaa`という項目の値が → `1`である」
「`bbb`という項目の値が → `2`である」
「`ccc`という項目の値が → `3`である」
という3つの情報が一塊りとなった物と言えます。
んで、話を戻して`flex`という項目はどういう意味かというと、一言で言うと「画面占有エリアの比率」です。今は恩恵をあまり受けてないのでわかりづらいですが、とりあえず`{ flex: 1 }`はスマホ画面一杯を占有するって意味なんだなと覚えていただければ大丈夫です。
さてこれで横スクロール型の部品が完成したのですが、いかんせん表示する内容をまだ書いていないのでスマホ画面上には何にも表示されません。なのでScrollViewタグ内(<ScrollView>と</ScrollView>の間)に表示したい内容を書いていくのですが、その場にベタ書きしちゃうとこれまたゴチャゴチャになってしまうので、ここは一旦新たな関数`renderSlides()`を`render()`の直上に作成することにします。
class WelcomeScreen extends React.Component {
renderSlides() {
}
render() {
return (
<ScrollView
horizontal
pagingEnabled
style={{ flex: 1 }}
>
{this.renderSlides()}
</ScrollView>
);
}
}
んで、新しく作った`renderSlides()`関数内に細かな挙動を書いていく、という算段です。`render()`関数からすると`renderSlides()`関数は最早`render()`の中にあるものではなくなるので、`this.renderSlides()`のように先頭に`this.`を付けて呼び出さなければいけません。この場合`this`は「WelcomeScreen」の事を指し、ドット`.`は、「〜の中の」という意味を指します。`render()`の中にはないけど、同じ`WelcomScreen`というコンポーネントの中という意味では一緒だから、`this.`(≒WelcomScreenコンポーネントの中の)を付けることによって呼び出せるようになります。同じ部屋にはいないけど同じ屋根の下で一緒に暮らしてるよね、的な感じです。
では`renderSlides()`関数の中身を書いていきましょう。今回の横スクロールは似たような内容を3ページ分表示させたいので、配列というテクニックを用いて似たような物を3個作りましょう。配列というのは複数の似た者同士を一つにまとめたもので、そうすることによってプログラム上で色々便利なことができます。複数のものをひとまとめにすると言った意味では先ほどのJavaScriptオブジェクトと似ていますがちょっと違います。配列は属性の同じ物達をひとまとめにするのに対し、JavaScriptオブジェクトは属性の違う物達をひとまとめにします。例えば、
[ 会員番号001, 会員番号002, 会員番号003, 会員番号004, ... ]
は配列が適していますが、
{ 会員番号: 001, 年齢: 23, 加入年: 2018 }
はオブジェクトの方が向いています。
そして今回は似たようなスライドページを3ページ作るので、配列の方が適しています。配列は上述の通り角括弧`[ ]`で表現します。下記↓のように`import`文と`class`定義文の間に書きましょう。あ、`const`は変数の初回登場時に必ず書かなければいけない魔法の接頭辞です。
import React from 'react';
import { StyleSheet, Text, View, ScrollView } from 'react-native';
const SLIDE_DATA = [
{ title: 'Step: 1', text: 'aaa' },
{ title: 'Step: 2', text: 'bbb' },
{ title: 'Step: 3', text: 'ccc' },
];
class WelcomeScreen extends React.Component {
renderSlides() {
}
render() {
return (
<ScrollView
horizontal
pagingEnabled
style={{ flex: 1 }}
>
{this.renderSlides()}
</ScrollView>
);
}
}
export default WelcomeScreen;
今回は`{ タイトル, テキスト }`という2種類の属性を持ったオブジェクトを3つ、配列にぶち込んでます。また`import`文と`class`定義文の間、つまり`WelcomeScreen`コンポーネントの外に書いたことによって、`WelcomScreen`内のどの関数からも配列`SLIDE_DATA`の内容にアクセスできるようになります。
んで配列の何が良いかっていうと、繰り返し処理を超簡単に書けるんですよね。何万回も同じ計算を人間と違ってコンピュータは飽きずに一瞬でやってくれるって、まさにこの配列の恩恵なんですよね。それをやってくれるのが、JavaScriptに最初から備わっている`map()`関数です↓。
const SLIDE_DATA = [
{ title: 'Step: 1', text: 'aaa' },
{ title: 'Step: 2', text: 'bbb' },
{ title: 'Step: 3', text: 'ccc' },
];
class WelcomeScreen extends React.Component {
renderSlides() {
return SLIDE_DATA.map();
}
`配列名.map()`と書くと、その配列の中身を一個ずつ細切れにして各要素全てに繰り返し同じ処理をしてくれるという優れものです。その`map()`関数の中に、配列の各要素一個に対してどんな処理をするか細かく書いていきます。ここで出てくるのがアロー関数です。
React Nativeはバンバン新しい概念が出てきますね…(ノд-。)グスン
アロー関数とは、
( 入力 ) => {
// ゴニョゴニョ…色々な処理があったりなかったり
return ( 出力 );
}
のように名前すら付いてない関数のことです(厳密には無名関数と完全一緒ではないですが、本記事ではこれ以上立ち入りませんので気にしなくてOKです)。` => `の部分が矢印みたいだからアロー関数って呼ぶんですね。
const SLIDE_DATA = [
{ title: 'Step: 1', text: 'aaa' },
{ title: 'Step: 2', text: 'bbb' },
{ title: 'Step: 3', text: 'ccc' },
];
class WelcomeScreen extends React.Component {
renderSlides() {
return SLIDE_DATA.map(( map関数からの入力達 ) => {
return ( 水色のページを出力 );
});
}
今回は、`map()`関数から受け取った配列の一要素を入力とし → 水色のページを出力として返す、というアロー関数を書きます。
const SLIDE_DATA = [
{ title: 'Step: 1', text: 'aaa' },
{ title: 'Step: 2', text: 'bbb' },
{ title: 'Step: 3', text: 'ccc' },
];
class WelcomeScreen extends React.Component {
renderSlides() {
return SLIDE_DATA.map((slide, index) => {
return (
<View>
<Text>{slide.title}</Text>
<Text>{slide.text}</Text>
<Text>{index + 1} / 3</Text>
</View>
);
});
}
まずmap()関数からの入力は主に2つあります。
1. 配列の各要素の一つ…`slide`
2. 現要素の番号...`index`
つまり今回の場合、
ということになります(プログラミングの世界では先頭番号は1番目ではなくて0番目なので注意)。
そして出力の方は、ドット`.`(「〜の中の」という意味)を利用して
・{slide.title}
・{slide.text}
・{index + 1} / 3 ... `index`には常にプラス1しないと例えば先頭ページが3分の0ページ目になっちゃう汗
の3文書をTextタグを用いて出力しています。しかしここでReact Native特有のルールで、「`return ()`文はたった一つのタグしか返せない」というものがあります。したがって3つもあるTextタグ達は一つの大きなViewタグで包み込んであげなければいけません。Viewタグは包み込んだタグ達の背景というか下地になるので、例えば背景色を一気に変えたりとかできます(もしHTMLやった事ある方なら、divタグに似てると思ってもらって構いません)。なので早速今回の例に従って背景を水色に変えましょう↓。
class WelcomeScreen extends React.Component {
renderSlides() {
return SLIDE_DATA.map((slide, index) => {
return (
<View
key={index}
style={{ flex: 1, backgroundColor: 'skyblue' }}
>
<Text>{slide.title}</Text>
<Text>{slide.text}</Text>
<Text>{index + 1} / 3</Text>
</View>
);
});
}
背景色は`backgroundColor: '〇〇' `で変えれます(`C`は大文字です!)。変更可能な色一覧はこちら。そして`flex: 1`は「スマホ画面一杯に」という意味です(覚えてましたか?^^)。
また、styleプロパティの上にあるkeyプロパティは特に見た目や動作に影響を与えませんが、必要なものです(これ怠ると黄色い警告メッセージが出ます…)。`map()`関数のように何回も同じ処理をreturnする場合には、returnするパーツ(今回で言うViewタグ)に一意の識別番号をkeyプロパティで付けなきゃいけないというルールがあります。別に文字でも数字でも毎回変わる物なら何でも良いですが、配列の`index`は毎回必ず違くなる数字なので、そのままkeyプロパティに使わせて貰います。
ここいらで一旦シミュレータで動作確認してみましょう。そのためには、今書いていた`WelcomeScreen.js`を最初の大元である`App.js`に組み込まなければいけません。まず`App.js`に戻って、先程の`WelcomeScreen.js`をimportし、TextタグをWelcomeScreenタグに置き換えます↓。
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import WelcomeScreen from './screens/WelcomeScreen';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<WelcomeScreen />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
上記↑は`WelcomeScreen.js`ではなく`App.js`ですよ!お間違えなく!
それではExpo XDEに戻り、`Device`→`Open in iOS Simulator`をクリックしてiOSシミュレータを起動してみて下さい。もし既に起動済みの方は、ソースコードを保存したそばから変更が反映されているはずです。もし変更が反映されていないようだったら、`command⌘+r`で更新してみて下さい。
って、あれ……
これは配列の各要素`slide`(map関数からの入力)の幅が適切でないからです。現状幅は何も指定されていないので、Textタグの内容が全部入るだけの幅しかありません。
ここで`slide`の幅を、スマホ画面の横幅と同じ値に設定します。スマホの画面サイズ情報を入手するために、`react-native`から`Dimensions`をimportします。
import React from 'react';
import { StyleSheet, Text, View, ScrollView, Dimensions } from 'react-native';
const SCREEN_WIDTH = Dimensions.get('window').width;
const SLIDE_DATA = [
{ title: 'Step: 1', text: 'aaa' },
{ title: 'Step: 2', text: 'bbb' },
{ title: 'Step: 3', text: 'ccc' },
];
そして`Dimensions.get('window').width`と書けばスマホ画面の横サイズ、`Dimensions.get('window').height`と書けばスマホ画面の縦サイズが手に入ります。今回は画面横サイズの情報を`SCREEN_WIDTH`という名の変数に保存し、
import React from 'react';
import { StyleSheet, Text, View, ScrollView, Dimensions } from 'react-native';
const SCREEN_WIDTH = Dimensions.get('window').width;
const SLIDE_DATA = [
{ title: 'Step: 1', text: 'aaa' },
{ title: 'Step: 2', text: 'bbb' },
{ title: 'Step: 3', text: 'ccc' },
];
class WelcomeScreen extends React.Component {
renderSlides() {
return SLIDE_DATA.map((slide, index) => {
return (
<View
key={index}
style={{ flex: 1, backgroundColor: 'skyblue', width: SCREEN_WIDTH }}
>
<Text>{slide.title}</Text>
<Text>{slide.text}</Text>
<Text>{index + 1} / 3</Text>
</View>
);
});
}
アロー関数の中のViewタグのstyleプロパティに`width: SCREEN_WIDTH`を追加します。すると、
おお〜、大分近づいてきました!ここいらで実機テストしてみましょう!Expoの凄いところは、簡単に即実機テストできちゃうところです。まずはExpo ClientというスマホアプリをApp Store/Google Playからダウンロードして、Expoを起動しているパソコンと同じWiFiに繋いで下さい。
するとExpo ClientのProjectsタブに今立ち上がってるプロジェクトが出てくるので、それをタッチすると……実機でアプリがテストできます!!超簡単!!!このためにExpo使ってると言っても過言ではないほど凄い機能です……。是非実際にマウスではなく指でウェルカム画面を左右にスリスリしてみて下さい(笑)
イメージ図
配置とデザインを整えよう
しかしまだTextタグによる文章が画面左上に固まってるので、良い感じに中央揃えにしてあげましょう。Textタグ達の配置をコントロールするには、背景色の時と同じように、それらを囲んでいるViewタグのstyleプロパティをいじってあげれば良いです。
ここから先は
¥ 199
チュートリアル完成しましたらTwitterでのご報告お待ちしております!笑