【両OS対応】 React Nativeで爆速モックアップ/プロトタイプアプリを作ろう 1/3 【ｳｪﾙｶﾑ画面編】

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">有料だけど力作。無料パートだけでかなり試せる。 <a href="https://t.co/CMP6oETmyb">https://t.co/CMP6oETmyb</a></p>&mdash; 深津 貴之 / THE GUILD (@fladdict) <a href="https://twitter.com/fladdict/status/994409625041555456?ref_src=twsrc%5Etfw">May 10, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">こういうnote増えるのうれしい。｜【両OS対応】 React Nativeで爆速モックアップ/プロトタイプアプリを作ろう 1/3 【ｳｪﾙｶﾑ画面編】｜川西発之 / 陳発暉 <a href="https://twitter.com/ho_ttu?ref_src=twsrc%5Etfw">@ho_ttu</a>｜note（ノート） <a href="https://t.co/61CxkmcoIZ">https://t.co/61CxkmcoIZ</a></p>&mdash; 加藤 貞顕 (@sadaaki) <a href="https://twitter.com/sadaaki/status/994414824275689472?ref_src=twsrc%5Etfw">May 10, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

note.muの中の方からもコメント頂けました！ありがとうございます！

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">「起業したい!良いアイデアを思いついた!でも周りにエンジニアいない…よし自分でアプリ作ってみよう」<br>そんな人に向けた、添付動画のアプリを実際に作りながら読み進めていくチュートリアルnoteです。<br><br>React Nativeで爆速モックアップ/プロトタイプアプリを作ろう 1/3｜note<a href="https://t.co/Op93sfbC6g">https://t.co/Op93sfbC6g</a> <a href="https://t.co/bxGZJF6yK6">pic.twitter.com/bxGZJF6yK6</a></p>&mdash; 川西発之 / 陳発暉 (@ho_ttu) <a href="https://twitter.com/ho_ttu/status/994408304448176133?ref_src=twsrc%5Etfw">May 10, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

↑このシリーズの最終完成形

![ezgif.com-video-to-gif (9).gif](https://qiita-image-store.s3.amazonaws.com/0/207119/05159701-0d2f-c683-0640-bbdaed3d0c3e.gif)

↑この記事での目標

# この記事で得れる物

・上図のスマホアプリが作れるようになる
・React Nativeの流れを図で直感的にわかる
・なぜこのようにプログラミングをしたのかまでわかる

# この記事の対象者

* アプリ開発経験そんなない方
* Web系開発経験そんなない方
* でもまあほんのちょっとプログラミングかじった事ある方(かじるどころかなめた程度の方でもOKです！)

大丈夫です、僕も当時こんな感じでした。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などの超有名アプリ](http://facebook.github.io/react-native/showcase.html)もReact Nativeにどんどん乗り換えています。日本製アプリで言うと[メルカリ](https://www.wantedly.com/projects/96850)や[Progate](https://www.wantedly.com/projects/117391)もReact Nativeだそうです。理由は一言で言うと、**開発スピードが速い**からです。トレンドの移り変わりが激しい現代のITベンチャーにおいてこれほど嬉しい利点は他にないでしょう。

# この記事の目的は？

……と、つまり激アツなプログラミング言語なのですがいかんせん日本語のまとまった情報が少なく、僕が学ぶ際に非常に苦労したのでこのチュートリアル記事を執筆することにしました。

「起業したい！良いアイデアを思いついた！でもアプリ作ったことないし、だからといって周りにエンジニアもいない……よしここは一丁自分でプロトタイプを作ってみよう。Instagram立ち上げた人もメルカリの創業者も最初はプログラミング未経験から始めたんだし！」
……と意気込んで調べてみるものの、出てくるQiitaなどの記事はどれも既にある程度の知識を持ってる前提で話が進んでることがしばしば。いやソースコードだけ貼られてもわかんねえし、みたいな。

そこでこのReact Nativeを初学者でも簡単に学べれるようになれば、iOS/Androidの両アプリを一気に作れちゃうし、超速攻で手元にある実機で動作確認できるし、[リリース後はApp Storeの審査を待たずに細かな修正をできるし](https://qiita.com/kndoshn/items/9b95522ccaf5d2504f85#hot-code-push%E3%81%99%E3%81%94%E3%81%84)……と言ったベンチャーにとって非常に有利になる武器を持った状態からスタートできます。そして将来性ありまくりな言語であることは間違いなく、何より僕自身「アプリってこんな簡単に作れるんだ！」と感動したのでその感動をもっと広めたく執筆しました。

SwiftもKotlinもJavaScriptも知らなかった筆者がReact Native(≒JavaScript)を学ぶ際に実際に引っかかった点を主に、「もっとこうやって教えてくれたらいいのに」という視点から超初心者(かつての自分)向けにスクショ豊富で書いてます。**わかりやすさを優先**しているためざっくりとした説明が多く、本当の意味での正確性には欠けているかもしれません。ただ読み進めてコード書き写してくだけでそれなりのアプリが作れるようになる、そんな記事にしたいと思います。実際に**あなたのスマホ上で作ったアプリを動かします**ので、スマホからではなくPCからの閲覧推奨です。

作るアプリは"旅行記アプリ"です。過去に自分が行った国と日付を入力し、その時の思い出の写真とその旅行の3段階評価を付けて保存していく、というアプリです(Trip + record = Treco …のつもり)。まあ使い道があるかどうかはいいとして（笑）、このアプリにはよくある要素の

* 真ん中が `+` プラスボタンになってるタブ構成 & 画面遷移
* 日付等を選ぶプルダウンメニュー
* 地図や画像の配置
* レビューの中から良い / 普通 / 悪いを仕分けする方法

などが多く積み込まれており、かつ完成後に自分で色々操作してニヤニヤできる(コレ重要)という事で選びました。あとはこれらの基礎要素を応用して組み替えたりしていけば、大体頭の中で想像しているアプリを実装できるようになりますし、何よりこのチュートリアルシリーズを読み終わってる頃には、自力で検索して必要な情報だけを探せれるようになっています。

本記事では以上のような旅行記アプリの、初回起動時に現れるウェルカム画面までを実装するチュートリアルです。このチュートリアルシリーズの各記事の反響が良ければ続きも執筆します ;->

**1. [ウェルカム画面編](https://note.mu/cube0529/n/n4a130029dfe1)** ← 今ココ
**2. [ホーム画面編](https://note.mu/cube0529/n/nd9f242d4d43b)**
**3. プラスボタン編**

# 開発環境を整えよう

手始めとしてMacでiOSアプリを開発することを想定して開発環境を構築します。まずは[MacのApp StoreからXcodeをダウンロードします](https://itunes.apple.com/jp/app/xcode/id497799835?mt=12)。容量大きいんで結構時間かかります。

![Screen Shot 2018-04-29 at 01.25.25.png](https://qiita-image-store.s3.amazonaws.com/0/207119/22966d0a-6b05-0b67-45b9-90f920e3ec3a.png)

Xcodeのインストールが終わったら、少しXcodeの設定を確認します。画面左上のメニューから`Xcode` → `Preferences`に行き、

![2.jpg](https://qiita-image-store.s3.amazonaws.com/0/207119/f04fca4f-c6e4-de7a-c45c-357aeac8dcc8.jpeg)

`Locations`タブの`Command Line Tools`で一番最新のバージョンのやつを選択して下さい。

![3.jpg](https://qiita-image-store.s3.amazonaws.com/0/207119/96a26d43-581d-cb14-3a55-677997fad595.jpeg)

次にReact Nativeを開発するための下準備をしましょう。と言っても下準備に必要なもの達をインストールするためには、先にHomebrewというやつをインストールしなければいけません…。[Macからターミナルを開くと](https://www.sejuku.net/blog/4202)、

![4.png](https://qiita-image-store.s3.amazonaws.com/0/207119/3f30ef3c-cb9d-277a-efce-1f8bda6c3209.png)

![5.jpg](https://qiita-image-store.s3.amazonaws.com/0/207119/86c0dc1d-2cf4-e182-e663-222b184565a4.jpeg)

自分のMacの名前の横にドルマーク`$`があって、ドルマーク`$`の右側から文字が入力できるようになります。そこの領域に、

```console
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

上記のドルマーク`$`以降(/usr/bin/ruby~~の部分)をコピペしてエンターを押すと、何やら聞かれるので再度エンターを押して待ちます。Macのパスワード入力を求められたら素直にパスワードを入力して下さい、怪しいもんじゃありません笑。

上記のHomebrewのインストールが終わったら`$ brew`コマンドが使えるようになるので、その`$ brew`を使ってReact Nativeの下準備をします。

```console
$ brew install node
```

もちろんここでもドルマーク`$`以降(brew~~の部分)だけをコピペしてエンター。上記が終わったら、

```console
$ npm install npm@latest -g
```

をして下さい(これは`$ npm`自身を最新ver. にアプデするコマンドです)。最後に、

```console
$ brew install watchman
```

をして、下準備は完了です。そしたらいよいよ、最強のReact Native開発ツールである[Expo XDEをこちらからダウンロードします](https://xde-updates.exponentjs.com/download/mac)。ダウンロードを待っている間に、[こちらでExpoアカウントを作っておきましょう](https://expo.io/signup)。このアカウントが無いとExpo XDEが使えません泣。

![6.png](https://qiita-image-store.s3.amazonaws.com/0/207119/15fd404c-e6e3-ac2b-d77e-8cfd37cd5dae.png)

最後に実際にソースコードを書くエディターソフトですが、極端な話メモ帳ソフトでも何でも良いですが、僕はAtomを強くお勧めします。皆Atoma使ってます、本当です。[こちらからダウンロードしましょう](https://atom.io/)。

![7.png](https://qiita-image-store.s3.amazonaws.com/0/207119/915eac00-8228-b633-2f5a-422e543d1ae6.png)

はい、お疲れ様でした。ここまででや〜っと環境構築が終わりました笑。

# 実際にアプリを作ってみよう

さあ、ではここから実際にプログラミングを始めましょう。Expo XDEを起動し、つい先ほど作成したアカウントでログインして下さい。

![Screen Shot 2018-04-29 at 09.49.15.png](https://qiita-image-store.s3.amazonaws.com/0/207119/e51fdb18-dee9-5dd3-8fe5-287da62e8a92.png)

プロジェクトの新規作成で、

![9.png](https://qiita-image-store.s3.amazonaws.com/0/207119/bd832b4f-2dcc-5ce1-c4e4-19ff793ba26e.png)

Blankタイプを選び、好きなプロジェクト名を入力します。
(ここでは`ract-native-bakusoku`)

![10.png](https://qiita-image-store.s3.amazonaws.com/0/207119/e239c552-6e7e-5e2f-1bfd-aca201687371.png)


数分待つと…

![11.png](https://qiita-image-store.s3.amazonaws.com/0/207119/ed8e5942-f2d9-c2a2-0b9a-44f9275e90a1.png)

なにやら赤いメッセージも出てますが、全然大丈夫です。Atomで先ほど保存したプロジェクト`react-native-bakusoku`を早速開きましょう。

![12.png](https://qiita-image-store.s3.amazonaws.com/0/207119/5732db4e-a104-2919-8654-666c813881aa.png)

![13.png](https://qiita-image-store.s3.amazonaws.com/0/207119/e624d5d7-b071-cf19-f388-cb219c755f76.png)

そして既に勝手にいくつかのファイルが自動で作られており、その中の`App.js`の中身をのぞいてみます。

![14.png](https://qiita-image-store.s3.amazonaws.com/0/207119/05b13bb1-5ed1-6971-4ee5-b057f389029c.png)

なにやらもう既に色々書かれてますね……。ここがExpo XDEの便利な点で、私達の代わりに上記のようなプログラミング雛形を勝手に作ってくれます。ここでTextタグ

```html:App.js
<Text> ~~ </Text>
```

に囲まれた部分の文章を変えてみましょう。

```html:App.js
<Text>Open up App.js to start working on your app!</Text>

        ↓

<Text>Hello React Native!</Text>
```

ちなみに、<〇〇>と</〇〇>をセットで**〇〇タグ**と呼びます。
<〇〇>で開けて</〇〇>で閉じるまで、ずっと〇〇の効果が適用されます。

```html
<〇〇>←ここから〇〇の効果が始まり 〜 〇〇の効果はここまで→</〇〇>
```

んでTextタグは「タグ内の文書をアプリ画面に映し出す」という効果を持っているので、

```html:App.js
<Text>Hello React Native!</Text>
```

と書けばアプリ画面に"Hello React Native!"って出る、ということです。では`App.js`を保存して(`command⌘+s`でも保存できます)、早速アプリを起動して試してみましょう。AtomからExpo EDXに戻って、

![15.png](https://qiita-image-store.s3.amazonaws.com/0/207119/bb2a21bc-cf33-d2bb-aaef-9338a5ad00df.png)

`Device`→`Open in iOS Simulator`をクリック。

![16.png](https://qiita-image-store.s3.amazonaws.com/0/207119/8e93c834-9a78-1a19-e95f-2cf951bb19ea.png)

するとiOSシミュレータが起動します(結構時間かかります)。このiOSシミュレータを使いたいがために最初にXcodeをインストールしたのです笑。

![17.png](https://qiita-image-store.s3.amazonaws.com/0/207119/e375e8d2-e690-85fd-99bf-8bc84f61ac8d.png)
↑[画像引用元](https://qiita.com/ykubot/items/963df6499af5ffc3a0b2)

初回は恐らく上図のように聞かれるので`Open`をクリック。

![18.png](https://qiita-image-store.s3.amazonaws.com/0/207119/aa3ef1ff-5f17-778f-db19-b46f70e033f6.png)

![19.png](https://qiita-image-store.s3.amazonaws.com/0/207119/3ae3f2e4-ee58-8e01-75bb-b9e2c8d38c2f.png)

iOSシミュレータ側のExpo(上図右側のExpo XDEとはまた別物)が起動してから更に待つこと数十秒……

![20.png](https://qiita-image-store.s3.amazonaws.com/0/207119/282a469b-b10e-4b98-f351-eb1d59429510.png)

無事アプリが起動しました！ちゃんとTextタグの変更が反映されてます！

もしここでiPhone Xのシミュレータが起動しちゃった人は、iPhone 8に変更することもできます(本記事では以降iPhone 8でやっていきます)。

![21.png](https://qiita-image-store.s3.amazonaws.com/0/207119/aafc5b27-eeac-2378-865f-56c9d5396345.png)

`Simulator`→`Hardware`→`Device`→`iOS 〇〇.〇`→`iPhone 8`をクリック。すると、iPhone X(一台目)とiPhone 8(二台目)の二つのシミュレータが同時に動いている状態になり、その状態でiOSシミュレータを閉じます(`command⌘+q`でも閉じれます)。

![22.png](https://qiita-image-store.s3.amazonaws.com/0/207119/8e2d9615-617a-adaa-0b01-d6ba31a2b928.png)

iOSシミュレータが二つとも一気に閉じられるので、そしたら再度Expo XDEにて`Device`→`Open in iOS Simulator`をクリックすると今度は最初からiPhone 8シミュレータが起動します！

どうやらExpo XDEは最後に起動されたiOSシミュレータを次回も最初に開くので、逆にiPhone Xシミュレータに戻したくなった時は今の手順とは逆に、「iPhone 8の後にiPhone Xを開く」→「2つとも同時に閉じる」→「再度Expo XDEからiOSシミュレータを起動する」でOKです。

#JavaScriptの文法エラーチェック機能を追加しよう

さて、ここからアプリをガンガン作って行くのですがその前に、今後ずっとスーパー役に立つ文法エラーチェック機能を追加しておきましょう。この機能を追加する事でエラーを起こす回数がグッと減ります。

Atomを起動して`Atom` → `Preferences`とクリックし、

![22-1.png](https://qiita-image-store.s3.amazonaws.com/0/207119/daee5761-ed69-c7b0-0ef0-82f8c291e76e.png)

画面左側の`Install`タブへ行ってそこで`linter-eslint`と検索して下さい。

![22-2.png](https://qiita-image-store.s3.amazonaws.com/0/207119/d63058a7-b975-9928-f578-226fb1d0b486.png)

検索して出てきた`linter-eslint`(ロケットアイコン)と`linter`(ピカチュウアイコン)の両方をインストールします。

![22-3.png](https://qiita-image-store.s3.amazonaws.com/0/207119/8990a40d-5969-35a7-47a2-80a178182c52.png)

もし先に`linter-eslint`を先にインストールすると、「`linter-eslint`は`linter`も必要としますけど、そっちも入れて良いっスカ？」って言う青いメッセージが出てきます。まあ、青い方の`Yes`選んでもピカチュウアイコンの方の`Install`押しても一緒なんでどちらでも大丈夫です。

そしたら今度は[ターミナルを起動し](https://www.sejuku.net/blog/4202)、`react-native-bakusoku`のあるフォルダまで`$ cd`コマンドで移動します。

```console
$ cd ~/先ほど/Expo XDEで/指定した保存場所/react-native-bakusoku
```

そこで、

```console
$ ls
```

と打つと今どんなファイルが存在してるか見れるのですが、恐らく大体こんな感じになってるかと思います。

![29.png](https://qiita-image-store.s3.amazonaws.com/0/207119/2c08d03d-f54b-92b5-6d29-ae3227919121.png)

そこで下記の`$ npm`コマンドを実行します。

```console
$ npm install --save-dev eslint-config-rallycoding
```

何やらダウンロードが始まります。終わったら念のため再度、

```console
$ npm install
```

を実行して下さい。今度は`--save-dev eslint-config-rallycoding`は要りません。

最後に`react-native-bakusoku`フォルダ内に一個新しく設定ファイルを追加しましょう。Atomから`react-native-bakusoku`を右クリック → `New File`を選択し、

![22-4.png](https://qiita-image-store.s3.amazonaws.com/0/207119/f0b90304-8492-7c48-a5ae-9f0dbfeb6c54.png)

`.eslintrc`というファイル名を付けます。**先頭にドット**`.`を付け忘れないで下さい。

![22-5.png](https://qiita-image-store.s3.amazonaws.com/0/207119/6326b776-ff12-152b-e144-13a447a395ae.png)

そしてその`.eslintrc`に下記をコピペします↓。

```json:.eslintrc
{
  "extends": "rallycoding",
  "rules": {
    "arrow-body-style": 0
  }
}
```

![22-6.png](https://qiita-image-store.s3.amazonaws.com/0/207119/199c5343-2fda-5c25-93f5-14e773fbc8a3.png)

はい、今度こそ本当の意味で環境構築が終わりました笑。

# 横スクロールのスライドページを作ってみよう

ではここからどんどん作り込んでいきましょう！アプリ初回起動時に「このアプリの使い方」的な感じでよく出てくる、横スクロール3ページ分くらいのウェルカムページ(正式な名前わからない泣)を手始めに作ってみましょう。この記事の冒頭にもありましたGIFが完成図です↓。

![ezgif.com-video-to-gif (9).gif](https://qiita-image-store.s3.amazonaws.com/0/207119/5b83ac66-26b5-1649-5d1f-f7d200c72a9b.gif)

ヌルッとした感じで左右にスクロールでき、各ページにはステップ別の指示が書いてあり、最後のページには「さあ、始めよう！」なんて書かれたボタンが配置されてるアレです。

早速Atomに戻り、`App.js`にブァーってコードを書き始めるのかと思いきや、新しく別のファイルを作ってそこに書きます。どの言語でもそうですがプログラミングは一箇所に全部書くとごちゃごちゃになるし、どっからどこまでが同一機能なのかわかりづらくなるため、各機能ごとに独立して新たなファイルに書きます。んでそれら各ファイルを最後に一箇所の`App.js`に集約するっていう流れです。そうすることによって「A機能を修正したい！」となったら`A.js`ってファイルだけ弄ればいいし、「B機能がぶっ壊れた！」となれば`B.js`ってファイルだけ直せばよくなります(基本的に)。

ということで、一旦`screens`というフォルダを作って、その中に新規ファイル`WelcomeScreen.js`を新たに作りましょう！

![2.gif](https://qiita-image-store.s3.amazonaws.com/0/207119/c0b2e99c-fb68-8cbf-66e1-d0a0982c7286.gif)

`App.js`には雛形を勝手に作ってくれたExpo XDEですが、私達が新規に作ったファイルには雛形を自動では書いてくれません。なので真っ新な`WelcomeScreen.js`にReact Nativeの以下の雛形を自分達で書いていきます。

```WelcomeScreen.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';


class WelcomeScreen extends React.Component {
 render() {
   return (

   );
 }
}


export default WelcomeScreen;
```

まずはおまじないだと思って、↑上記を(コピペではなくキーボードで)書き写してください。

解説をすると、

```WelcomeScreen.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
```

はReact Nativeを使用するために絶対必要で、これ書かないと始まりません。

```WelcomeScreen.js
class WelcomeScreen extends React.Component {

​}
```

上記は`WelcomeScreen`という名の**コンポーネント**を作りますよ、という意味です。コンポーネントとは、一つのまとまった機能を表す部品みたいなもので、上述の通り基本的に1機能1ファイルなので1ファイル1コンポーネントとなります。

```WelcomeScreen.js
class WelcomeScreen extends React.Component {
 render() {
   return (

   );
 }
}
```

んでコンポーネントは必ず`render()`という名の**関数**を持っており、その`render()`関数が返す`return ();`の中身がアプリ画面上に描画されます。関数とは、何か入れると中でゴニョゴニョ加工されて姿形を変えて何かしらが返ってくるモノのことを言います。100円玉入れると→中でなんか処理されて→ジュースがボトンッて出てくる自販機と理屈は一緒です笑。入力が入る→中で処理される→出力が返ってくるの3ステップです。コンポーネントはまず最初に(和訳すると"描画する"という意味の)`render()`関数を実行し、→中でなんか処理したりしなかったりして、→`return ();`の中に書かれたことが返ってくる→アプリ画面上に描画される……という流れです。つまり`render()`の中の`return ();`内に書く内容にほぼ全てがかかってます。

※ちなみに`render()`の括弧前にスペースは無いのに、`return ();`のカッコ前にスペースが1つ有るのは、それで合ってます。ご心配なく。

```WelcomeScreen.js
export default WelcomeScreen;
```

最後のこの一文は、後にこの`WelcomeScreen`コンポーネントを`App.js`に集約させるときに必要な文章です。`App.js`から外部ファイル(≒外部コンポーネント)を取り入れることを**インポートする**と言いますが、そのためには`WelcomeScreen`が**エクスポートする**(取り出す)ことを許可しなければいけません。こういうとこいちいち書かないとすぐエラーなっちゃうのがプログラミング言語の頭固いとこですね汗。

それでは早速重要な`return ();`の中身を書いていきます。React Nativeは便利なもので、スクロール機能を実現するためのScrollViewタグ(`S`と`V`が大文字なので注意)というものが既に用意されており、我々はその使い方に従って書けばいいだけで、自前で一から作成する必要はありません。

```jsx:WelcomeScreen.js
class WelcomeScreen extends React.Component {
  render() {
    return (
      <ScrollView>
      </ScrollView>
    );
  }
}
```

<〇〇>で開いたタグはちゃんと</〇〇>で閉じるのを忘れないでください！それからScrollViewタグ自体も`WelcomeScreen.js`にとって外部である`react-native`からインポートしておかなければ、エラーなってしまいます。

```WelcomeScreen.js
import { StyleSheet, Text, View, ScrollView } from 'react-native';
```

なので↑上記のように中括弧`{ }`の中に`ScrollView`を追加して下さい(`S`と`V`が大文字なので注意)。

この状態で既に縦スクロールできる状態になってますが、このままでは希望の動作から大分遠いので、

* `horizontal`…スクロール方向を横にする
* `pagingEnabled`…ヌルッ→ピタって感じで1ページごと止まるようにする
* `flex: 1`…描画エリアをスマホ画面上一杯を占有するようにする

の3オプションをScrollViewタグに追加します。こういった追加オプションは下記↓のように開始タグの中に書くことによって反映され、一応**プロパティ**って名前が付いてます。

```WelcomeScreen.js
<ScrollView
  horizontal           // horizontal={true}でも可
  pagingEnabled        // pagingEnabled={true}でも可
  style={{ flex: 1 }}
>
</ScrollView>
```

ここで疑問となるのが、なぜ中括弧`{ }`が一重の時と二重の時があるのかということですね。まず一重にしろ二重にしろ、一番外側の中括弧`{ }`は、「今からこの中括弧の中にJavaScriptを書きますよ〜」という合図です。

ん、待てよ…ってことは<〇〇>タグとかはJavaScriptじゃないの…？

正解です笑。ここがまたReact Nativeをややこしくする点なんですけど、React NativeはJavaScriptだけでなくHTML風のやつ(正式名称はJSX)も書けるというルールなんです。そしてボタンの配置位置とかは全てこのHTML風のやつ、つまり<〇〇>タグを使って記述します。しかしそのHTML風のやつの中に更にまたJavaScript書きたくなる時があって(ややこしい汗)、その時は中括弧`{ }`で囲ってからJavaScriptを書く、というルールです。

![23.png](https://qiita-image-store.s3.amazonaws.com/0/207119/881183e6-6296-9b15-b84e-e9ebd1e2a80e.png)

じゃあ二重の中括弧`{ }`はどうなっているかと言うと、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()`の直上に作成することにします。

```jsx:WelcomeScreen.js
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`は**変数**の初回登場時に必ず書かなければいけない魔法の接頭辞です。

```jsx:WelcomeScreen.js
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()`関数です↓。

```WelcomeScreen.js
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はバンバン新しい概念が出てきますね…(ノд-。)グスン*

アロー関数とは、

```js
( 入力 ) => {

  // ゴニョゴニョ…色々な処理があったりなかったり

  return ( 出力 );
}
```

のように名前すら付いてない関数のことです(厳密には**無名関数**と完全一緒ではないですが、本記事ではこれ以上立ち入りませんので気にしなくてOKです)。` => `の部分が矢印みたいだからアロー関数って呼ぶんですね。

```WelcomeScreen.js
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()`関数から受け取った配列の一要素を入力とし → 水色のページを出力として返す、というアロー関数を書きます。

```jsx:WelcomeScreen.js
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`

つまり今回の場合、

![24.jpg](https://qiita-image-store.s3.amazonaws.com/0/207119/55db56a6-048a-18fb-ffbb-70c628154605.jpeg)

ということになります(プログラミングの世界では先頭番号は1番目ではなくて**0番目**なので注意)。

そして出力の方は、ドット`.`(「〜の中の」という意味)を利用して

* {slide.title}
* {slide.text}
* {index + 1} / 3 ... `index`には常にプラス1しないと例えば先頭ページが3分の0ページ目になっちゃう汗

の3文書をTextタグを用いて出力しています。しかしここでReact Native特有のルールで、「`return ()`文はたった一つのタグしか返せない」というものがあります。したがって3つもあるTextタグ達は一つの大きなViewタグで包み込んであげなければいけません。Viewタグは包み込んだタグ達の背景というか下地になるので、例えば背景色を一気に変えたりとかできます(もしHTMLやった事ある方なら、divタグに似てると思ってもらって構いません)。なので早速今回の例に従って背景を水色に変えましょう↓。

```jsx:WelcomeScreen.js
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`は大文字です！)。変更可能な色一覧は[こちら](https://facebook.github.io/react-native/docs/colors.html#named-colors)。そして`flex: 1`は「スマホ画面一杯に」という意味です(覚えてましたか？^^)。

また、style **プロパティ**の上にあるkey **プロパティ**は特に見た目や動作に影響を与えませんが、必要なものです(これ怠ると黄色い警告メッセージが出ます…)。`map()`関数のように何回も同じ処理をreturnする場合には、returnするパーツ(今回で言うViewタグ)に一意の識別番号をkeyプロパティで付けなきゃいけないというルールがあります。別に文字でも数字でも毎回変わる物なら何でも良いですが、配列の`index`は毎回必ず違くなる数字なので、そのままkeyプロパティに使わせて貰います。

ここいらで一旦シミュレータで動作確認してみましょう。そのためには、今書いていた`WelcomeScreen.js`を最初の大元である`App.js`に組み込まなければいけません。まず`App.js`に戻って、先程の`WelcomeScreen.js`をimportし、TextタグをWelcomeScreenタグに置き換えます↓。

```jsx:App.js
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`で更新してみて下さい。

![3.gif](https://qiita-image-store.s3.amazonaws.com/0/207119/dd8fb000-8a76-216e-1d50-310a9f77edcf.gif)

って、あれれ〜…

![25.jpg](https://qiita-image-store.s3.amazonaws.com/0/207119/346185b0-1fd4-a33a-dee1-53294a63fc13.jpeg)

これは配列の各要素`slide`(map関数からの入力)の幅が適切でないからです。現状幅は何も指定されていないので、Textタグの内容が全部入るだけの幅しかありません。

ここで`slide`の幅を、スマホ画面の横幅と同じ値に設定します。スマホの画面サイズ情報を入手するために、`react-native`から`Dimensions`をimportします。

```WelcomeScreen.js
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`という名の**変数**に保存し、

```jsx:WelcomeScreen.js
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`を追加します。すると、

![4.gif](https://qiita-image-store.s3.amazonaws.com/0/207119/e8319bdd-f027-78fc-c5f0-9e54ac2b58a6.gif)

おお〜、大分近づいてきました！ここいらで実機テストしてみましょう！Expoの凄いところは、簡単に即実機テストできちゃうところです。まずは[Expo Client](https://expo.io/tools#client)というスマホアプリをApp Store/Google Playからダウンロードして、Expo XDEを起動しているパソコンと同じWiFiに繋いで下さい。

次にExpo **XDE**の`Share` → `Send Link`とクリックすると入力したメアドもしくは携帯電話番号(SMS)にリンクが届きます。携帯電話番号の人は、090の最初の0を+81に変えて、090 → +8190 のようにしてください。ハイフンはあってもなくてもどっちでも。

![26.png](https://qiita-image-store.s3.amazonaws.com/0/207119/d7531d05-b52c-50e7-a951-6c05fce1e35f.png)

届いたリンクを押すと先ほどのExpo **Client**が立ち上がって……実機でアプリがテストできます！！超簡単！！！このためにExpo使ってると言っても過言ではないほど凄い機能です……。是非実際にマウスではなく指でウェルカムページを左右にスリスリしてみて下さい（笑）

[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/Hj_Eu5tlm0s/0.jpg)](http://www.youtube.com/watch?v=Hj_Eu5tlm0s)

↑イメージ動画

# 配置とデザインを整えよう

しかしまだTextタグによる文章が画面左上に固まってるので、良い感じに中央揃えにしてあげましょう。Textタグ達の配置をコントロールするには、背景色の時と同じように、それらを囲んでいるViewタグのstyle **プロパティ**をいじってあげれば良いです。

*この続きはnote.muにて*

https://note.mu/cube0529/n/n4a130029dfe1

(残り16,854文字 / 画像10枚)

[![Screen Shot 2018-06-09 at 20.00.40.png](https://qiita-image-store.s3.amazonaws.com/0/207119/a861cfc6-8e94-5e3c-8688-55cbe359dbf6.png)](https://note.mu/cube0529/n/n4a130029dfe1
)