React Native 2016 年の動き

React Native とは ?
-------------------

一発目なので簡単な紹介から。 React.js と同様、仮想 DOM で UI を記述できるモバイルアプリ作成用の JavaScript フレームワーク。特徴としては次のようなものがある。

- EcmaScript 2015
- 宣言的
- コンポーネント指向
- CSS ライクなスタイル指定
- flow による型チェックサポート

公式で取り上げられている使用例は次にまとめられている。

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

思想は次のページで説明されている。これは去年の記事。

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

重要だと思う点をとりあげる。

### keep development velocity: 開発速度を落とさない

> One of the most painful things about our transition to mobile, though, is how much it's slowed down our development velocity.
> When building on the web, we can simply save our files and reload the browser to see the result of our changes. On native, however, we need to recompile after every change, even if we just want to shift text a few pixels over on the screen. As a result, engineers end up working a lot more slowly, especially in a large codebase where compilation is especially burdensome.

> モバイル開発への移行にあたって一番苦痛だったのは開発速度がどの程度落ちたのかということだった。
Web 開発では、単純にファイルを保存しブラウザーでリロードすれば結果が見えた。しかしネイティブではテキストの表示位置を数ピクセル変えるだけの変更であっても、そのたびに再コンパイルが必要になった。結果として、エンジニアの仕事速度は大幅に落ちた。特に大きなコードベースではその影響が大きかった。

### learn once, write anywhere: 一度学んだらどこでも書ける

> It's worth noting that we're not chasing “write once, run anywhere.” Different platforms have different looks, feels, and capabilities, and as such, we should still be developing discrete apps for each platform, but the same set of engineers should be able to build applications for whatever platform they choose, without needing to learn a fundamentally different set of technologies for each. We call this approach “learn once, write anywhere.”

> 我々は「一度書いたらどこでも動く」ということに価値があると思っていない。異なるプラットフォームは異なる外見、手触り、能力を持つ。そのため、まだプラットフォームごとに個々のアプリを開発すべきだと考えている。が、同じチームが、選んだプラットフォームすべてで、基礎的な技術の違いを学ぶことなしにアプリケーションを作成できなければならない。我々はこのアプローチを「一度学んだらどこでも書ける」と呼んでいる。

ニュース
--------

4 月の Facebook の開発者向けイベント F8 で Microsoft の協力を得て Windows を、 Samsung の協力を得て Tizen をサポートすることを発表した。

https://techcrunch.com/2016/04/13/facebooks-react-native-open-source-project-gets-backing-from-microsoft-and-samsung/

が、現時点の状況が何も発表されていないので、来年に持ち越しかも。同じく F8 で発表するということもありうる。

今年の変更点
------------

主に semver でいうマイナーバージョンが上がるが、まだメジャーバージョンが 0 なので breaking change 上等のアップデートが多い。

2 週間を目処にアップデートされている。たまに数日ずれる。

プラットフォームに依存しない各バージョンの変更点を大雑把に見ていく。 Android / iOS におけるエンハンスは着実に進んでいる。

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

プラットフォームごとの変更は他プラットフォームではサポートされていたコンポーネント、 props 、 API をサポートした、ブリッジを書きやすくした、パフォーマンスが向上した、などが多い。

### 0.18.0

https://github.com/facebook/react-native/releases/tag/v0.18.0

2016/01/19 リリース。

- `react` npm package に直接依存するようになった
    - これまでは `react-haste` というものへの依存で一段かましていた

### 0.19.0

https://github.com/facebook/react-native/releases/tag/v0.19.0

2016/01/30 リリース。

- `scrollTo` メソッドが `ListView` に追加された
- iOS9.2 / Xcode 7.2 へ環境移行された
- テキストノードを除いて背景色の継承がなくなった

### 0.20.0

2016/02/16 リリース。

https://github.com/facebook/react-native/releases/tag/v0.21.0

- WebSocket の Origin その他のリクエストヘッダーを変更可能になった
- カメラロール関連を `Promise` を使って処理できるようになった
- テキストフィールドのオートリサイジングが追加された
- Babel preset が定義された
- 画像以外のアセットをバンドルできるようになった

### 0.21.0

https://github.com/facebook/react-native/releases/tag/v0.21.0

2016/03/02 リリース。

- `NavigationExperimental` が追加された
    - 既存の Navigator は状態を持ってしまっていたので、状態を持たずに redux などで一元管理可能なナビゲーション用のコンポーネント
    - https://facebook.github.io/react-native/docs/navigation.html#navigationexperimental
- `dataSource` が更新されたときに自動的に表示が更新されないよう変更された
- 色に数値を指定できるようになった
    - `0x1a2b3c` など
- `Navigator` コンポーネントの `onWillFocus` / `onDidFocus` を使っても警告が出ないようになった
- `NetInfo` にリスナーを登録した際、解除する関数を返すよう変更された
- `require` ではなく `import` を使うようドキュメントに明示された

### 0.22.0

https://github.com/facebook/react-native/releases/tag/v0.22.0

2016/03/21 リリース。

- hot reloading 対応
    - https://facebook.github.io/react-native/blog/2016/03/24/introducing-hot-reloading.html
- `ListView` にカスタムした `ScrollView` を渡せるようになった
    - 横スクロールする `ListView` などはこれで実現する
- Touchable 系コンポーネントに `disabled` prop が追加された

### 0.23.0

https://github.com/facebook/react-native/releases/tag/v0.23.0

2016/04/07 リリース。

- bundle 時にログを出力しないためのオプション `silent` が追加された
- 何らかの `Promise` が `reject` された場合 `console.error` もしくは赤い背景でエラー表示するようになった
- `NavigationExperimental` を用いて `Navigator` が実装された

### 0.24.0

https://github.com/facebook/react-native/releases/tag/v0.24.0

2016/04/19 リリース。

- いくつか iOS のタッチ / スクロールイベントが拾えていなかった点を修正
- `NavigationExperimental` が改良された
    - ページャーにアニメーションとジェスチャーがついた

### 0.25.1

https://github.com/facebook/react-native/releases/tag/v0.25.1

2016/05/05 リリース。

- `react-native` からではなく、 `react` から React API を `import` するよう変更になった
    - `View` などコンポーネントは引き続き `react-native` から `import` する
    - 本家 React.js の API が使えるため Learn once, write anywhere が徹底された
    - 引き続き `react-native` からも `import` 可能
- Chrome Developer Tools 以外の JavaScript デバッガーを使えるようになった
    - `REACT_DEBUGGER` という環境変数に使いたいデバッガーの起動コマンドをセットしておくと使えるようになる
- `Image` コンポーネントに `prefetch` メソッドが追加された
    - あらかじめ画像をキャッシュしておくためのもの
    - https://facebook.github.io/react-native/docs/image.html#prefetch
- `XMLHttpRequest` の `ontimeout` と `onerror` をサポートした
    - が、 `fetch` を使うのが推奨されている
    - https://facebook.github.io/react-native/releases/next/docs/network.html

### 0.26.0

https://github.com/facebook/react-native/releases/tag/v0.26.0

2016/05/19 リリース。

- `react-native` から React API を `import` できなくなった
    - `react` からでないと `import` できない 0.25.1 での変更が強制された
- React 15.0.2 へアップグレードした
- WebSocket でバイナリーデータを送受信できるようになった
- `react-native` コマンドに `--version` オプションが追加された
- `react-native bundle` サブコマンドに `--reset-cache` オプションが追加された
    - 通常バンドルされたソースはキャッシュされるが、そのキャッシュを削除するオプション

### 0.27.0

https://github.com/facebook/react-native/releases/tag/v0.27.0

2016/06/06 リリース。

- ソフトウェアキーボード関連のイベントハンドラーの登録に `DeviceEventEmitter` を使っていたのを `Keyboard` を使うようになった
    - https://facebook.github.io/react-native/releases/next/docs/keyboard.html
- インスペクターから対応コンポーネントのソースファイルが開けるようになった
- rnpm を取り込んだ

### 0.28.0

https://github.com/facebook/react-native/releases/tag/v0.28.0

2016/06/22 リリース。

- `PullToRefreshView` が廃止になり、 `onRefreshStart` / `endRefreshing` を使うよう変更になった
    - 現在は `ListView` の `onRefresh` イベントを使う
    - https://facebook.github.io/react-native/docs/refreshcontrol.html
- パフォーマンスの問題から `flexWrap: 'wrap'` と `alignItems: 'stretch'` を同時に指定できなくなった
    - `alignItems` は `'stretch'` がデフォルトなので `flexWrap: 'wrap'` を使いたい場合他のものに設定する必要がある

### 0.29.0

https://github.com/facebook/react-native/releases/tag/v0.29.0

2016/07/06 リリース。

- Android ソースが変更
    - `MainApplication.java` が追加になった
    - 手動でのアップグレード方法は↑に書いてある
- Android で `password` prop ではなく `secureTextEntry` prop のみを使えるように変更された
- Android で `Profiler Option` が開発用メニューから削除された
- `StatusBarIOS` が削除、 `StatusBar` に統一された
- `react-native` コマンドにログを表示するためのサブコマンド `log-ios` / `log-android` が追加された
- 警告の黄色い表示にスタックトレースを表示するようになった
- `react` npm package の依存が `^` から `~` に変更された
- `KeyboardAvoidingView` が追加された
    - https://facebook.github.io/react-native/releases/next/docs/keyboardavoidingview.html
- カメラロールから動画を選択できるようになった
- ソースをリロードするときにデバッグコンソールを消去するようになった
- `InteractionManager` のタスクをキャンセル可能になった
    - https://facebook.github.io/react-native/releases/next/docs/interactionmanager.html
- flexbox で `flexDirection` に `'row-reverse'` / `'column-reverse'` を指定できるようになった
- `Text` に `lineBreakMode` を指定可能になった
    - 現在は `ellipsizeMode`
    - https://facebook.github.io/react-native/releases/next/docs/text.html#ellipsizemode

### 0.30.0

https://github.com/facebook/react-native/releases/tag/v0.30.0

2016/07/21 リリース。

- VSCode をエディターとして使えるようになった
- `react-native` コマンドから iOS シミュレーターのバージョンを指定できるようなった
- `zIndex` が使えるようになった
    - http://facebook.github.io/react-native/releases/next/docs/layout-props.html#zindex

### 0.31.0

https://github.com/facebook/react-native/releases/tag/v0.31.0

2016/08/08 リリース。

- rnpm の取り込みが完了した
    - `react-native link` で `rnpm` 相当のことができる
- `enqueueJSCall` に呼び出し完了時のコールバックを指定できるようになった
- `TextInput` に onContentSizeChange が追加された
- `fetch` で空ボディが返ってきたときのエラーメッセージがマシなものに変更された
- Navigator が RTL をサポートするようになった
- 警告の黄色い表示のファイル名と行数をタップするとそのファイルを開くようになった

### 0.32.0

https://github.com/facebook/react-native/releases/tag/v0.32.0

2016/08/21 リリース。

- 別ユーザーへの送信や SNS への投稿をするための `Share` API が追加された
- `ActivityIndicator` コンポーネントに `size` prop が追加された
- インスペクターにネットワーク通信の中身を表示する UI が追加された
    - XMLHttpRequest や WebSocket の情報も表示可能となった
- `Navigator` コンポーネントに `popN` メソッドが追加された
- `TextInput` コンポーネントに `dataDetectorTypes` メソッドが追加された
    - 入力内容のうち、電話番号やリンクなどを検出してジャンプできるようにする
- React Native Packager のシンボリックリンクサポートが部分的に追加された
- React Native Packager が動いていないときのメッセージがわかりやすく変更された

### 0.33.0

https://github.com/facebook/react-native/releases/tag/v0.33.0

2016/09/09 リリース。

- `react-native` コマンドに `rn-cli.config.js` のパスを渡す `--config` オプションが追加された
- `flex-grow`, `flex-shrink`, `flex-basis` がスタイルに指定可能なプロパティとして追加された
- 単純なファイル変更の際のリロード時間が短縮された
- スタイル指定時の flow による型チェックが厳密化された
- 複数のデバイスに対して run-android する際、すべてのデバイスに対して `adb reverse` するように変更された
- アニメーション設定に `onComplete` が追加された

### 0.34.0

https://github.com/facebook/react-native/releases/tag/v0.34.0

2016/09/23 リリース。パフォーマンス向上のための変更が多数なされている

- `RCT_NO_LAUNCH_PACKAGER` 環境変数が設定されていると React Native Packager を立ち上げないよう変更された
- タイマーがより精度の高いものに変更された
- Jest メジャーバージョンが 15 に変更された
- ポート番号がすでに塞がっているときにエラーコード 11 で終了するよう変更された

### 0.35.0

https://github.com/facebook/react-native/releases/tag/v0.35.0

2016/10/11 リリース。

- `PushFromLeft` アニメーションが `Navigator` に追加された
- `react-native init` 時に Jest がインストールされるようになった
    - `skip-jest` オプションでインストールさせないことも可能
- package.json の `browser` に `false` を指定すると何もしないよう変更された

### 0.36.0

https://github.com/facebook/react-native/releases/tag/v0.36.0

2016/10/25 リリース。

- `ScrollView` に `flexShrink: 1` がデフォルトで指定されるよう変更された
- `Keyboard` API に `dismiss` メソッドが追加された

### 0.37.0

https://github.com/facebook/react-native/releases/tag/v0.37.0

2016/11/08 リリース。

- 非推奨コンポーネントがいくつか削除された

| 削除                      | 代替              |
|---------------------------|-------------------|
| AppStateIOS               | AppState          |
| ActivityIndicatorIOS      | ActivityIndicator |
| IntentAndroid, LinkingIOS | Linking           |
| SliderIOS                 | Slider            |
| SwitchAndroid, SwitchIOS  | Switch            |

- Clipboard, NetInfo のコールバックインターフェイスが削除、 Promise で代替するように変更された
- `Button` コンポーネントが追加された
    - えっ、いまさら… ?
- `HorizontalSwipeJumpFromLeft` アニメーションが `Navigator` に追加された

### 0.38.0

https://github.com/facebook/react-native/releases/tag/v0.38.0

2016/11/23 リリース。ドキュメントのアップデートなどが同時になされている。

- `MapView` を非推奨にし、 https://github.com/airbnb/react-native-maps を使うよう変更された
- yarn 0.16.0 以上がインストールされている場合、 `react-native init` 時に yarn を使うように変更された