React Native for Androidでアプリを作ったときにハマったこととかの話

<div class="alert alert-success text-center"><i class="fa fa-android"></i> この記事は <a href="http://qiita.com/advent-calendar/2016/dwango">『ドワンゴ Advent Calendar 2016』</a>6日目の記事です。</div>

( ・ｘ・）ﾉ やぁ！ るたんだよ。

昨日は hajimehoshi さんの[『JavaScript の prototype の復習』](http://qiita.com/hajimehoshi/items/f4a46bdc26d0466c76f8)でした。
prototype 何となくで理解した気になってしまっていたので復習大事でした！

## この記事はなに？

- ReactNativeが熱いらしいが結局どうなんだろ？
- 普段ネイティブアプリ作ってない僕が実際に使ってみたら結構よかった
- いくつかハマったことがあるので書いた

## どういうわけか？

普段、ぼくはRubyをメインに使っているのですが、
最近はいろいろあってJavaScriptも触ったりしています。

そんなJSの中で魂が震えるほど熱いのがReactですが、
Reactファミリーには『ReactNative』と呼ばれる
スマホなどのネイティブアプリをつくるためのライブラリがありまして、
ここ2ヶ月くらいちょっぴり触って、アプリをつくったりしていました。

…というのも『○○を使えばWebの知識でアプリつくれるぜ！』みたいな
甘い誘惑は昔からよく聞くことがあるのですが、
実際に触ってみると全然Webの知識関係なかったり、
ただのWebViewでブラウザじゃん！だったりと、
大体がハズレなイメージがあったため、
今回はReactNativeが本物なのかどうかを確かめたかったのです。[^todo]

[^todo]: TODOアプリじゃあんまり参考にならないしネ

結果としてはアプリも無事リリースし、
「お、結構いけんじゃん！？」という気持ちになったので、
そこまでの間で困ったことなどを記事にしたいと思います。

## 実際につくったもの

<img src="https://qiita-image-store.s3.amazonaws.com/0/25109/9e2102bf-a1cf-8105-88bc-be6226e00ed8.jpeg" width="320">

- アプリ： [CompacReader](https://play.google.com/store/apps/details?id=com.toripota.compacreader)
- コード： [rutan/compac-reader](https://github.com/rutan/compac-reader)

「小説家になろう」リーダーです。
きれいな縦書きで読めるやつが欲しかったので今回の題材にしました。
[『賢者の弟子を名乗る賢者』](http://ncode.syosetu.com/n6829bd/)を読むことが僕の生きがいです。

## 困ったこと、ハマったこと

### Realm DBを入れたらアプリのデバッグが死ぬほど遅い……

- [realm/realm\-js](https://github.com/realm/realm-js)

まだまだオフラインでも動くWebページをつくる機会は少ないため、
Webフロントではあまり縁のないクライアント側のDBですが、
ネイティブアプリとなると、さすがに必須です。

最近iOS/Androidアプリ開発では熱いモバイルDBの [Realm](https://realm.io/jp/) ですが、
最近は ReactNative や node.js から利用できる
JavaScript版が提供されているため使ってみることにしました。

が！
入れたところデバッグが急激に遅くなってしまいました。。。

原因は　ReactNativeの `Remote JS Debugging` を有効にしていたためです。
これを有効にすると Chrome の DevTools から各種ログを見たり大変便利なのですが、
Realm　の DB アクセスが全て母艦のPC経由で行われてしまうようで、
シャレにならないレベルで動作が遅くなります。。。

仕方ないので、 `Remote JS Debugging` を無効にし、
ターミナルで `react-native log-android` を実行することで、
ログを表示するようにして回避しました。かなしみ。

### `<View>` を出したり消したりしたらガクガクする……

画面をタップするとメニューが出たり消えたりするような画面を作ろうとしました。
以下のようなイメージです。

```sample-component.js
render() {
  return (
    <View>
      { this.state.isShow ? <Menu /> : null }
      ...
    </View>
  );
}
```

これを実際に動かすと、すごくカクカクします。
さすがにネイティブのUI部品を生成するコストはだいぶ高いみたいですね。
この辺りはHTMLでやるときより気を使ってあげる必要があります。

出したり消したりする場合はホントに消すのではなく、
style を切り替えて画面上に見えないようにする方向でやることにしました。

### 『何もしてないのに壊れた』

React Native には Hot Reload があるため、
コードを編集して保存した瞬間に実機に反映することができます。

「うーん、サイコ〜〜〜」と言いながらViewをどんどん組み上げていたのですが、
うっかり初期化時に通る処理に手を加えてしまったりして、
Hot Reloadではそこを通過しないため気付かず、
次の日に続きをやろうとしたら動かなくなっていた！
といった事件（？）がありました。

ちゃんと確認しようね！（通しで動かすとか、CIでテスト回すとか）

## まとめ

ReactNativeでアプリをつくったので、
その際に困ったことやハマったことをまとめました。
困ってググって来た方など、何か参考になれば幸いです。

ちなみにハマったことだけ書くと
なんだか良くないみたいになっちゃうので最後にベタ褒めしておくと、

- ホントに普段のWebの知識でアプリが書けた
    - react + redux みたいないつもの組み合わせ
    - npm のライブラリも使える
    - Componentの中身もほぼいつもどおり
- まるでWebページを書いているかのように開発できた
    - ビルドは最初の１回だけでOK [^build]
    - エディタで編集したら Hot Reload で実機に即反映

[^build]: ただし、ネイティブ系のコンポーネントライブラリを新しく npm install したときはビルドが必要です

"learn once, write anywhere" という言葉のとおり、
本当に普段のWeb開発をしているような感覚でアプリが書くことができ、
神、いわゆるゴッドでした。

また別のアプリつくる機会があったら使おうと思います！
みんなもハッピー Reacting![^vue]

[^vue]: 僕は個人プロダクト大体Vue.jsなんですけどね

## おまけ
ReactNativeでつくったって言ってるけど、
実は縦書き表示してる本文の部分は WebView 実装なんだ。すまない。

やっぱりWebって最高！！！！！！！！！！！！！！！！！！！！１１１１１１１１１１１１