React + Redux + TypeScript でWebアプリを作った感想・勉強法と Angular との比較

# 作ったもの

成果物は [Alcatraz を便利に検索する Alcatraz Search という web アプリを開発しました](http://qiita.com/star__hoshi/items/fc6895ca4c9a40e739a7) を参照ください。
ソースコードは [starhoshi/AlcatrazSearch](https://github.com/starhoshi/AlcatrazSearch) にあり、 [GitHub Pages で公開](http://starhoshi.github.io/AlcatrazSearch/) されています。

今回作るためにした勉強や開発の感想、 React と Angular の比較などをつらつら書いていきます。
多少なりともフロントの心得がある人向けで、あまり説明的ではない内容です。

# フロントエンド開発経験

* 2015年7月くらいから業務で Angular, TypeScript, Browserify, gulp やらで Cordova 製のスマホアプリを開発。
  * 半年ちょいのニワカです。
* [AlcatrazSearch](https://github.com/starhoshi/AlcatrazSearch) は仕事終わりと土日に開発して 1 ヶ月かかった。
  * 勉強のための開発なので、期間は目安といった感じ。
  * あと業務の方が :fire: 炎上してひたすら働いていたのもあって時間がかかった。


# 使った主なライブラリの感想と勉強方法

## [react](https://github.com/facebook/react)

勉強は [チュートリアル | React](https://facebook.github.io/react/docs/tutorial-ja-JP.html) をやった後に、[WEB+DB PRESS 86](http://gihyo.jp/magazine/wdpress/archive/2015/vol86), [87](http://gihyo.jp/magazine/wdpress/archive/2015/vol87) で連載していた伊藤直也さんの react と flux の連載記事を読んだ。
それ以外では [mozaic.fm#13](http://mozaic.fm/post/106264251221/13-virtual-dom) や [rebuild.fm#114](https://rebuild.fm/114/) などの Podcast を聞いて勉強した。

ユーザアクションなどがあり表示を変更する際、どの DOM をどう変更するかというのを意識せず全ての DOM を再レンダリングする感覚で書いていけるので富豪的プログラミングと言われているようだ。
富豪的と言っても VirtualDOM というので差分計算をして更新してくれる。([React概論](http://sssslide.com/speakerdeck.com/naoya/reactgai-lun) に詳しく書いてある)

React は JSX という XML ライクな記法で HTML を書いていくため、それが嫌だという人もいるが、個人的には JSX に違和感なかった。
ソース内に JSX を書いていくため、 components 1 つ 1 つを小さくしないとコードの見通しが悪くなる。意識して components を分割して作るようになって良いと思う。

[React Components](http://react-components.com/) も便利。
[react-bootstrap](http://react-components.com/component/react-bootstrap) を使ったので css もほとんど書いていないし、 [react-highlighter](http://react-components.com/component/react-highlighter) で検索結果のハイライトもサクッと実装できた。

## [redux](https://github.com/reactjs/redux)

[flux](https://github.com/facebook/flux) フレームワーク。厳密には Flux ライクなフレームワーク。
Redux 以外にもいろいろあるが、 GitHub Star の数と [Fluxフレームワーク戦争の現状確認（前編）](http://amagitakayosi.hatenablog.com/entry/2015/12/02/172453) を読んで、 Redux にした。

今回使った中で一番理解に時間がかかった。
[Read Me | Redux](http://redux.js.org/index.html) を一通り読んでから [redux/Examples.md](https://github.com/reactjs/redux/blob/master/docs/introduction/Examples.md) と [todomvc-redux-react-typescript](https://github.com/jaysoo/todomvc-redux-react-typescript) を比較しながら読んで勉強した。

勉強後も開発を始めると「container と components の違いってなんだっけ...」とか「State? Store? Reducer? Action? あれ何がどう違うんだっけ」となるので、その度に [Read Me | Redux](http://redux.js.org/index.html) に立ち返り確認した。

何かユーザの入力などで変更があった場合、その変更を action が dispatch し reducer が処理する流れとなるのだが、今回は reducer でやることがほとんどなくただ冗長なだけになってしまった。
どう表示するかなどは結局 View の react でやっているし、もうちょっとビジネスロジックが多くなって来ないと良さがわからないのだろうたぶん。

* Redux について良いと思った記事
  * [ReactとFluxのこと // Speaker Deck](https://speakerdeck.com/geta6/reacttofluxfalsekoto)
  * [fluxフレームワークreduxについてドキュメントを読んだメモ - fukajun - 僕はvimで行きます -](http://fukajun.org/66)
  * [人気のFluxフレームワークReduxをさわってみた - マルシテイア](http://amagitakayosi.hatenablog.com/entry/2015/07/30/000000)
  * [ReduxとES6でReact.jsのチュートリアルの写経 - bokuweb.me](http://blog.bokuweb.me/entry/redux-tutorial)
  * [Redux ExampleのTodo Listをはじめからていねいに(1) - Qiita](http://qiita.com/xkumiyu/items/9dfe51d2bcb3bdb06da3)


これを書きながら [mizchi の Redux 考](http://togetter.com/li/911228) を読んでもよく理解できなかったので、もっと Redux 内部のコード読むなどして理解深める必要あると思った。

## [TypeScript](https://github.com/Microsoft/TypeScript)

業務でも使っていてとても良いので個人でも使った。
勉強方法は [Tutorial - Welcome to TypeScript](http://www.typescriptlang.org/Tutorial) をやっただけ。

やはり型があると安心感がある。
コンパイルしなきゃいけないのと型ファイルが必要なのが面倒だが、エディタが型エラー出してくれるのでコンパイル時間の元は取れると思う。型ファイルは頑張れば作れる。
いくつか型ファイルを作ったが、 [typings/registry](https://github.com/typings/registry) にはまだ PR 送ってないのでそのうち PR 出す。

また、 React の propTypes の validation は TypeScript の型でできるのでそれも相性が良い。

# React + Redux vs Angular

React + Redux と Angular の違いや、感じたメリット・デメリットなど。

## React Components vs Angular Directive

React Components の方が使い勝手良いと感じている。
外部ライブラリの Angular Directive を使う場合 app.js で最初にロードする必要があるが、 React Components は単に require して使える。

Angular Directive は多機能だが覚えることがとても多く使いこなすまでが大変だが、 React Components はシンプルで HTML が書ければなんとかなる感がある。

## Flux vs data-binding

初めて Angular の data-binging を見たとき、「変数を変えるだけで HTML 反映されるしすげーなこれ」と思った。
ただ、`$scope.watch` して状態の監視をしたり、 `$scope.apply` を実行しないと data-binding が機能しなかったりしててハマることが多々あった。

その点 Flux だと状態が変わるたびに DOM のレンダリングが走るため直感的だし余計なことをしなくて良い。回りくどいのだが理解できれば違和感のない流れとなる。

## JSX vs HTML

View で React を使うと、デザイナーが JSX を書く必要があるため、そこの分業がなかなか難しいなと思った。
Angular は `.html` で書くのが可能なので HTML だけコーディングしてもらい開発側で `ng-*` を埋め込むというように分業できる。
[JSといえばjQueryだったWebデザイナーが、Reactを1年間使って感じたメリット](http://creator.dwango.co.jp/3413.html) のようにデザイナーが JS をかければ良いが...。
今の業務では HTML を外部に納品してもらってるので、その HTML を開発側で JSX に置き換えるのは大変と感じた。

## ライブラリの組み合わせ vs フルスタックフレームワーク

Angular はフルスタックのため基本的に必要なものはデフォルトでほぼカバーされている。
Redux は http 通信をするためにも [redux-thunk](https://github.com/gaearon/redux-thunk) や [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch) などを npm install する必要がある。

全体が疎結合であるといえばそうなのだが、どのライブラリを使うのか選定する時間が発生するし、ドキュメントがバラバラなので組み合わせ時にハマって時間を食ッタリする。
全てをデフォルトで用意してくれる方が開発効率が良く機能の連携などがうまくいくため、変にハマり時間が取られることが少ない。

実際 Angular の httpInterceptor は業務で使った時にログインや共通処理を作成するのに便利だったし、標準でそれがあるのは良い。

Angular に全てを身を捧げ、2.0 になってもついていく覚悟があるなら Angular に投資するのも有りだと思う。

## 個人的な感想

感想としては、 Angular に全て身を捧げるより他のライブラリを自由に組み合わせていく方が性に合ってるし色々なライブラリを触れて楽しい。

React 触ったあとに Angular で Directive 書こうとするとウッってなって React 最高感を感じた。

条件にもよるが、自分が好きに作って良いならば React で開発すると思う。
Flux フレームワークは Redux と [fluxxor](https://github.com/BinaryMuse/fluxxor) しか触ったことないので、他のも触ってちゃんとソースを読みたい。

# フロントエンド開発に対する愚痴

今までの話とあまり関係がない話になるが、何も知らない状態からフロントエンドの開発環境を構築する壁が高いと感じる。

TypeScript と webpack を使おうと思ってサンプルレポジトリを見ると、package.json, typings.json, tsconfig.json, webpack.config.js, .babelrc, .npmrc それらに紐づくライブラリや設定ファイルなど大量にあってめまいがする...。
やりたいことをやり始めるまでに時間がかかってしまい、この段階で心折れる人がそれなりにいるんじゃないかと思う。

そういう人は webpack や各種設定ファイルの理解とかは置いておいて、現状動いているサンプルプロジェクトを clone してとりあえず動かしてやりたいことやれば良いと思う。
必要に応じて設定変えないと動かない時は来るし、色々やっているうちに「この設定いらないんじゃないか」とわかるようになると思います。

# 最後に

[starhoshi/AlcatrazSearch](https://github.com/starhoshi/AlcatrazSearch)

React, Redux, TypeScript 全て経験が浅く間違った認識やコードがあると思うので、マサカリやプルリク、コメントなどお待ちしています。