React.js × React Native meetup アンケート質問に答えたい

React.js × React Native meetup 申込時にもらっていた質問をパネルディスカッションで答えようとしたものの時間がなくてお蔵入りになってしまったがそれはもったいないので答えていくコーナー。

https://react-native-meetup.connpass.com/event/49024/

パネルディスカッションでしゃべった内容とも重複しているところがある。

↓も参考に。

https://speakerdeck.com/januswel/what-is-react-native

以降 React Native を RN と略する。


データフロー
------------

### Web では React/Redux がデファクトスタンダードだが RN ではどうか ?

flux データフローを使わずに済む規模であれば導入コストもばかにならないので React のみで書くのがよい。

MobX で書いている方を知っているが、小規模なのでわかりやすさ重視で書きたいとのこと。
それ以外は Redux しか聞いたことがない。

↓MobX と Redux の比較について React Conf 2017 でセッションがあったらしい。

http://hackerslab.aktsk.jp/2017/03/14/133739#MobX-vs-Redux-Comparing-the-Opposing-Paradigms-Preethi-Kasireddy

好きなようにすればいいと思うが、チームでやるなら単純な技術選定なので次あたりで決めていけばいいのでは ?

- 実際に使われているのか ?
    - npmjs.com でのダウンロード数
    - github.com のスター数
- シンプルか ?
    - 理解するのにコストかけないといけないのか ?
- チームメンバーにとって理解しやすい情報が豊富か ?
    - それは今後も持続されるか ?

### 大規模での flux の store の管理をどうやっているか ?

一般的にどれくらいから大規模なのかわからないが、データ構造設計は基本なので業務に合わせてやればいいのでは ?
ただ、モバイルアプリでしっかり設計しないとダメなくらい大規模になるプロジェクトは考え直したほうがいい気がする。

### RN と相性のいい mBaas は何か ?

モバイルアプリは目的ごとに大別できると思っていて、それごとに扱いやすいバックエンドを選べばいいはず。

- ユーザー間のリアルタイムコミュニケーションが主
    - Firebase
- データビューアー / プレイヤー
    - GraphQL
        - Relay
- ユーザーをサポートするエージェント的なもの
    - DDD でいうドメインモデルをしっかりくんでそれに適したバックエンドを選ぶ
    - REST でも HTTP/2 があるのでまじやばいトラフィックでもない限り十分なのでは


メリット・デメリット
--------------------

### RN のアンチパターンや、気をつけていることはあるか ?

RN 固有のアンチパターンは特にない。 ECMAScript 2015, npm, babel, React.js, Xcode, gradle などでの経験がしっかり生きる。

flow を使っている場合は、 RN 本体のバージョンに束縛される点に注意。最近は安定しているのであまり問題にならないと思うが。

実現したい機能は大体すでに誰かが書いているのでまず探せばいいが、技術選定に近いので↑で書いた選定基準を参考に。

### RN が向いているケース、向いていないケースを教えてほしい

まず向いているケース。↓の項目はすべて達成できる。

- React.js で書ける開発者が
- 短期間で
- iOS / Android 対応の
- UI/UX に優れたアプリを作る

ここらへんは↓に思想も含めて書いてある。

https://code.facebook.com/posts/1014532261909640/react-native-bringing-modern-web-techniques-to-mobile/

かいつまむと、↓の感じ。

- ネイティブの体験
    - プラットフォームネイティブの UI を使える
- Learn once, write anywhere
    - React.js を知っていればどのプラットフォーム向けにも書ける
- 開発速度を落とさない
    - ビュー層の微調整にかかる再コンパイル時間を短縮できる

向いてないケースは圧倒的にゲームなど、ハードウェアを直接叩かないとユーザーに価値を届けられないアプリ。逆を言うとそれ以外はなんでもいけると思っている。


選定にあたって
--------------

### RN は実務で使えるか ?

使える。↓使っているアプリ一覧。

https://facebook.github.io/react-native/showcase.html

日本では Togetter, CureApp など。

### RN の将来性はどうか ?

ロードマップも整備されているし、 Facebook は HTML5 -> native -> React Native という歴史を辿ってきているので捨てられる可能性はかなり低い。

https://github.com/facebook/react-native/wiki/Roadmap

また、パネルディスカッションでも言ったが、 React.js は宣言的にビュー層を書いていくためのツールで、 RN は対応するプラットフォームを増やすだけと考えると React.js の興隆がそのまま RN の将来性につながる。

### RN の学習コストは ?

最低限、次が必要だが大体これでなんとかなる。

- React.js
- npm, yarn
- Xcode / gradle

すべてググれば出てくるが、 React.js 以外の tips は↓にまとめている。

http://qiita.com/janus_wel/items/d3c5b695015cb54344ff

デフォルトでいくなら babel の知識は必要ないが、 stage-0 の機能が使いたいなどカスタマイズが必要になったらきちんと向き合わないといけない。

チーム開発では flow, ESLint なども導入したほうがよいので敷居は上がる。

つぎの場合は Objective-C, Swift, Java や各プラットフォームのアプリケーションライフサイクルなどネイティブの知識も必要。

- デバイスの機能にアクセスしたいが既存パッケージで提供されていない
- 既存パッケージのネイティブ層の処理がイケてないので自分で書きたい
- 重い処理をネイティブ側にディスパッチしたい

ただし、たいていの機能は既存パッケージで提供されている範囲であまり問題にならない。

npm エコシステムを知らない状態でネイティブから RN という流れはツライかもしれないが、 Objective-C の動的バインディングや Java の型とたたかってきたネイティブエンジニアなら乗り越えられるハードルだと思っている。

これは学習コストというよりチームとしてどうするかというハナシだが、ひとりネイティブ層を知っている人間がいればトラブル解決も容易になる。が、その人間に頼りっきりというのはバス係数が低いままなので、 RN をチームで触りながらスキルトランスファーしていくのがよいと考えている。

### iOS と Android で共通化はどの程度できるか ?

どの程度の品質を求めるかによるが、やろうと思えばまったく同じソースコードで共通化は可能。

現実的なラインは UI レベルのコンポーネントを共通化、画面コンポーネントは各プラットフォーム向けに作り込むというのがよいと考えている。


運用
----

### マルチプラットフォームにおいて RN の運用方法は ?

一般的なハナシだが、プロダクトで提供するバリューは各プラットフォームにおいても同じと考えると、ひとつのチームでマルチプラットフォーム対応したほうがプロダクトオーナーの息吹をきちんと吹き込むことができるはず。

規模にもよるが、たいていの場合で RN を使って 1 チームでのマルチプラットフォーム対応が十分可能だと考えている。現に 2 プラットフォームなら 4 人でいけた。

### RN の version up はどれぐらい追いかけてるか ?

バージョンアップがあればカジュアルに追従している。が、 breaking change があると使っているパッケージ側の追従が追いつかないのでその場合は待ったり、 contribute している。

breaking change のあるバージョンアップは xcodeproj の差分 merge という特殊技能がない場合、使っているパッケージに対して `react-native link` で再設定してやる必要があるので時間はかかる。が、慣れれば 2 時間くらいで済む。

https://github.com/facebook/react-native/tree/master/react-native-git-upgrade

### RN のテストを自動化しているか ?

CureApp での事例になるが、 React コンポーネントを dumb に作って、 props の値によって描画内容が切り替わるなど複雑なコンポーネントのみ mocha + enzyme でテストを書いている。

http://qiita.com/janus_wel/items/9a1d1e9e93f28bb9aaad

いわゆる E2E テストはコスパが悪いのでやっていない。人間が触ったほうが精度も良い。
標準の Jest の売りであるスナップショットテストはメリットがない気がしている。

reducer, action creator など Redux についてはユニットテストをがっつり書く。コスパよく書けるし、書いたほうが品質を担保できるからだ。

### RN のブリッジで気をつけてることは何か ?

単にデバイスの機能を使いたい場合は JS 層へのインターフェイスだけ切って、非常に薄く作る。問題にならない限り状態を持つなど「頭のいい」インターフェイスは作らない。本家でも言っている "scripting native" という発想でそれらを使って JS 層でいい感じに書く。

https://code.facebook.com/posts/1014532261909640/react-native-bringing-modern-web-techniques-to-mobile/

ネイティブ層に重い処理をディスパッチしたい場合はメモリー消費など気をつけてよしなにやる。

### RN での navigation はどう実現しているか ?

現在絶賛過渡期。

- react-navigation
    - https://reactnavigation.org/
    - コミュニティの推し
        - https://facebook.github.io/react-native/docs/navigation.html#react-navigation
    - 画面コンポーネントにナビゲーション用のデータを定義しなければならない
    - まだこなれていない
- react-router-native
    - https://github.com/ReactTraining/react-router/tree/master/packages/react-router-native
    - react-router の RN 版なので知見や感覚を使いまわせるのではという期待
    - ただしあまりネイティブとして自然な遷移にならないという噂
- native-navigation
    - https://github.com/airbnb/native-navigation
    - React Conf 2017 で大々的にアナウンスされた AirBnB 製
    - 導入が手間らしい
- react-native-router-flux
    - https://github.com/aksonov/react-native-router-flux
    - 簡単な遷移であればサッと作れるが、少し複雑なことをしようとすると闇しかない
    - テストが非常に書きにくい
    - 去年までのデファクトスタンダード
- NavigationExperimental
    - 標準で提供されている
    - 状態を持たず、開発者がいい感じに制御できる
    - 今年はこれかと思いきやまさかの deprecated 指定
        - https://facebook.github.io/react-native/docs/navigation.html#navigationexperimental

react-navigation, react-router-native, native-navigation のどれかだと思うがまだ検証中。