React Native 一問一答

# 1問１答
React NativeのTipsを、備忘録も兼ねて１問１答形式で記述したいと思います。
開発をする前に気になってたところ、疑問などをを１問１答形式でまとめてみました。
随時アップデート予定です(2016/12/23現在)
<b>編集リクエスト、追加、修正大歓迎です。よろしければお願いします。</b>

# 基本
## React Nativeとは何ですか？
Facebook製のモバイルアプリ向けのフレームワークです。[公式](https://facebook.github.io/react-native/)
HTMLベースのフレームワークと異なり、Reactで培った仮想DOMを元にネイティブコードを呼び出します。そのため挙動が軽快です。
実際は後ろでJavascriptのランタイムが動いていて、ネイティブコードを呼び出してくれています。

## React Nativeのメリットは？
たくさんあると思いますが、最大の特徴はFacebookが提言する"learn once, write anywhere"の体現です。
私はWeb開発者なので、swiftは遊びでしか触ったことありませんでしたし、Androidは2.0の化石の知識でしたが、iOS、Android両プラットフォームを開発することができました。
ある程度まではWeb開発の知識(React.js)でいけます。

上記を踏まえたメリット
* iOS、Android間でコードが共通化できる(体感的に7　~ 8割)
* Javascript(ES6)が使え、swift、Javaの異なる言語の学習が不要
* 各プラットフォームのライフサイクルを意識せずかける(React.jsに合わせる)
* Web開発の知見が使える(npmのエコシステム)
* Flexboxでレイアウトがわかりやすい
* Javascriptランタイムの恩恵でBuildせずリロードができるReactiveに開発できる(地味に開発が早くなるw)

## React Nativeのデメリットは？
React Nativeはほとんど、React.jsでかけます。逆に言うと、React.jsを知らないと辛いです。
また、用意されていないComponentの自作する必要があります。Objective-C(iOS), Java(Android)の知識が必要です。
Componentの多くは提供されている & 外部moduleが用意されているので問題ありませんが、
用意のない細かい挙動を求める分は自作が必要でしょう。工数との相談になるところです。

上記を踏まえたデメリットとしては、

* Componentを自作 or 外部moduleの拡張する場合は、iOS, Androidの知識が必要
* version更新が多く、外部moduleがメンテナンスされてなくて使えなくなってるケースがある(オレオレ拡張が必要)
* Bugがあった時、Google検索で見つけにくいです。出ても英語でエラー解決に時間を有する場合がある。
* 日本語の記事がすくなく、学習は英語のドキュメントを読むことが必須。

## どのタイプのアプリ開発に向きますか？
ゲーム以外のモバイルアプリ開発だと思います。
[本家のShowCase](https://facebook.github.io/react-native/showcase.html)を見るとアプリの傾向がわかります。
有名どころで言うと、
[Facebook](https://itunes.apple.com/app/facebook/id284882215),[Instagram](https://itunes.apple.com/app/instagram/id389801252?mt=8)はReact Native製に変わってます。

## どんな人が向いてますか？
React NaitiveはJavascriptを使用します。そして多くがWeb開発の知識を使えます(Flexboxやnpmなど)
よって、Web開発者がアプリ開発を手がける際が一番向いてるでしょう。
また、アプリ開発者でもクロスプラットフォーム開発に興味がある人も対象だと考えます。

## 使用できるコンポーネントに不足がありますか？
[ドキュメントのCompnents](https://facebook.github.io/react-native/docs/getting-started.html)を参照して下さい。
不足しているモノがあるかもしれませんが、多くは[OSS](https://github.com/jondot/awesome-react-native)で補完されています。
APISも参考になります。[シェア](https://facebook.github.io/react-native/docs/share.html)、[アニメーション](https://facebook.github.io/react-native/docs/animated.html)、[プッシュ通知](https://facebook.github.io/react-native/docs/pushnotificationios.html)など、おおよそ使うであろう機能は実装されています。

## ここにないコンポーネントはどうしますか？
React Nativeはネイティブコードを呼び出す仕組みが備わっています。そのため、[iOS](https://facebook.github.io/react-native/docs/native-modules-ios.html)、[Android](https://facebook.github.io/react-native/docs/native-modules-android.html)しかないコンポーネントや自作コードを呼び出すことが可能です。

## iOSやAndroidのエコシステムは使えませんか？
少し踏み入った話になりますが、iOSは[Cocoapodを使用することができます](https://facebook.github.io/react-native/docs/integration-with-existing-apps.html)。Androidはgradleで外部moduleを取得することができます。

## 参考アプリは何が良いですか？
実践アプリは[f8](https://github.com/fbsamples/f8app)一択だと思います。
フェイスブックのカンファレンスで使用されたアプリでRNの宣伝も兼ねてるから作り込みが半端ないです。
プラットフォームの分け方、データ構造、とても参考になります。

F8は大きすぎるので、以下も良いでしょう。
[Haker News](https://github.com/iSimar/HackerNews-React-Native)

## そうは言ってもパフォーマンスが気になる
実際のアプリを確かめるのが一番早いです。

[公式](https://facebook.github.io/react-native/docs/performance.html)では、
 60 FPS and a native look & feel to your apps.
と記載があります。60fpsとは一般のネイティブアプリのデフォルトのフレームレートだそうです。
特にListViewのパフォーマンスは最適化されていると感じました。
2000アイテムを持っていたとしても、描画されるのは見えてる部分でスクロールの度再生成してくれます。

javascriptランタイムのおかげで非同期処理が得意です。
ただし、裏で動かし過ぎるとカクカクなってくるので、遷移の時は初期処理を待つなど、[処理順を考えて設計する](https://facebook.github.io/react-native/docs/performance.html#slow-navigator-transitions)必要があります。

## バージョンめっちゃ変わってるけど大丈夫？
React Nativeは２週間サイクルを目安にアップデートするよう公式が言ってます。
後方互換は残していると言ってますが、

* ver0.25 -> ver0.26 (CoreがReact Native -> ReactとReact Nativeに分けられる)

のようにコア部分の変更があり、外部moduleが動かなくなるケースもあるので、バージョンは注意した方が良いでしょう。

## いつまでメンテナンス続きますか？
Facebook公式発表はわかりませんが、[本家](https://facebook.github.io/react-native/showcase.html)がReact Native製に変わっていることを考えると、FaceBookの目の黒いうちは安泰なのかな？と思ってます。(Parseの件もあるので安心はできませんが)
とはいえ、この問題はどのフレームワークも同だと思います。様々な要因をジャッジして選択しましょう！

# 開発について

## 開発環境にしていはありますか？
使い慣れたエディタで充分です。
[Deco](https://www.decosoftware.com/)というReact Native用のIDEがありますが使ったことはありません。
私はatomを使用しています。pluginでeslintがかけれたりして便利です。

## 開発言語は何ですか？
[javascript](https://facebook.github.io/react-native/docs/javascript-environment.html)(というより、React.js)を使用します。

## レイアウトはどのように指定しますか？
Flexboxを使います。
レイアウトは予想外に手馴染みが良かったです。まるでWeb開発のようにコーディングすることができました。
swiftを学んだ時、制約は理解しがった内容の一つです。Androidはxmlで、両プラットフォームで異なるレイアウト指定はおそらく音をあげてたでしょう。
Flexboxをはじめとした[CSSライク](https://facebook.github.io/react-native/releases/next/docs/stylesheet.html)な書き方ができたのは嬉しかったです。

## iOSとAndroidどこまで共通化できますか？
共通できるのは以下です。

* flux/reduxのデータフロー周り
* 共通のコンポーネント

iOSとAndroidでは考え方が違うのでレイアウトの配置を分ける必要も出てくるでしょう。
ただし、コンポーネント全て分けるかといったらそうではなく、7割、８割共通化できた印象です。

## iOS、Androidどうやってロジック分けるの？
分岐で分けるか、元から分けるかの２通りあります。

* 分岐：[Platform](https://facebook.github.io/react-native/docs/platform-specific-code.html)を使う
* 元：ファイルをfile.ios.jsとfile.android.jsに分ける

## 外部moduleは何がありますか？
https://github.com/jondot/awesome-react-native
にまとめられています。必要なものはだいたい揃っている印象です。
良いモジュールはiOSとAndroidの違いをうまく吸収し、React Native側では共通コードで書くことができます。
歴史が少ない分、洗練はされてないのでレイアウトはお察し部分もあります。

## 多すぎて何が良いやら。。。
[ソート検索](https://js.coach/react-native?sort=popular)ができるサイトがあります。

便利だと思ったもの一部紹介
アイコン：https://github.com/oblador/react-native-vector-icons
ナビゲータ周り：https://github.com/aksonov/react-native-router-flux
スクロールタブ：https://github.com/skv-headless/react-native-scrollable-tab-view
マップ(airbnb製)：https://github.com/airbnb/react-native-maps
カメラ：https://github.com/lwansbrough/react-native-camera
ネイティブモジュールのリンク(最近内部に取り込まれた)：https://github.com/rnpm/rnpm
Blur：https://github.com/react-native-community/react-native-blur
アニメーション：https://github.com/oblador/react-native-animatable
デバイスの詳しい情報：https://github.com/rebeccahughes/react-native-device-info

## 使いたいけど開発止まってるや。。。
基本的には互換性があり、過去のものでも使用することができますが、エラーの場合はオレオレ拡張するか自作しましょう。

# 発展編

## サーバーサイドってどうするの？
サーバーサイドはJSONで受け取ります。
サーバサイドがすでにあるならJSONを送るAPIを作成するか、mBaasを利用しましょう。

オススメは[firebase](https://firebase.google.com/)です。
過去に[React + Redux + Firebaseで作るTodo App](http://qiita.com/gonta616/items/278a7e81a8b624d9621e)という記事を書きましたが、ほぼReact Nativeに置き換え可能です。

## Debugってどうするの？
DebugはChromeで行います。
iOSの場合、cmd + D, Androidは右下のボタンから、Debug JS Remotelyを選択します。
Chromeの画面が立ち上がるので、検証 -> Sourceで下記のようにDebugが可能です。
<img width="296" alt="スクリーンショット 2016-12-22 0.33.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/56423/6b6296fa-8851-32b1-fd5c-a042fe3280db.png">

他にも、Perfomance測定や画面のリロードを行うことができます。

## 各デバイス対応ってどうすればよい？
Flexboxが優秀です。flex:1としておけば、基本横幅いっぱいに広がってくれます。
デバイスサイズで処理を変えたい場合は、[Dimensions](https://facebook.github.io/react-native/docs/dimensions.html)が便利です。

```
const window = Dimensions.get('window');
window.width
window.height
```

でデバイスの幅を取得することが可能です。

また、解像度ですが、以下のように2倍、３倍のサイズを用意しておくと、デバイスに合わせて自動で合った解像度を選択してくれます。

* back.android.png
* back@2x.android.png
* back@3x.android.png

## なんか赤い画面が出た
エラーです。びっくりしますが、落ち着いて対処しましょう。
[Issue](https://github.com/facebook/react-native/issues)にだいたい上がってます。

## MVCパターンとかありますか？
React.jsと同じデータフローを使用することができます。沢山moduleがありますが、FluxかReduxが有名です。
Reduxはオブザーバーのデザインパターンに新しく名前をつけたものです。Qiitaでもたくさん良記事が上がってるので一読の価値ありです。

* [React+Redux入門](http://qiita.com/erukiti/items/e16aa13ad81d5938374e)
* [Redux入門【ダイジェスト版】10分で理解するReduxの基礎](http://qiita.com/kiita312/items/49a1f03445b19cf407b7)

React Nativeの特筆すべきところは、[react-redux](https://github.com/reactjs/react-redux)でComponentを紐付けるところまで、すべてReact.jsと同じ書き方ができるところです。reduxを知っていればそのまま使うことが可能です。
redux, react-redux, redux-thunk, redux-loggerなどなど

## HTTP通信をしたい。
ajaxではなく[fetch](https://facebook.github.io/react-native/docs/network.html)を使用します。
callbackはthenで待ちましょう。
fetchについてはこの記事がわかりやすいです。
[お疲れさまXMLHttpRequest、こんにちはfetch](http://qiita.com/tomoyukilabs/items/9b464c53450acc0b9574)

## フォルダ構成はどのようになりますか？
特段の決まりはありませんが、以下のような構成が多いと思います。以下はflux/reduxのフローを採用したケースです。
React Nativeのコードとネイティブコードは分かれます。
ios (ネイティブ)
android (ネイティブ) 
src (React Native)
 - actions (http通信周り)
 - components (部品レベル)
 - containers (ページレベル/reduxとconnectする部分)
 - reducers (actionを受けてstateを変更するめそd)
 - store (アプリケーションの状態を保持する)

# 最後に
開発前気になってたけど、聞けなかったことをまとめてみました。
クロスプラットフォームは荊の道が多く、触るのに勇気がいると思います。
触ってみたいけど、一歩が出ないという方の参考になれば幸いです。

また、React Nativeの技術者の方に役立てれば幸いです。