ゼロから始めるElectron - 2週目 「ReactとRedux」

#はじめに
Electronの学習を始めて2週目が過ぎましたので、情報をまとめたいと思います。
使う技術については、スクリプト言語をES2015(ES6)、フレームワークにReact、
Flux実装はReduxにしました。
理由は早くリッチな画面コンポーネントを使いたいからです。

今回のまとめは、ほとんどがReactとReduxになります。
ゼロからという割に、少し難しく感じるかもしれませんがよろしくお願いします。
今の理解を整理するために書いています。


どんな画面コンポーネントがあるかは下の図も参照ください。

###これまでの記事
1．[ゼロから始めるElectron - 1週目](http://qiita.com/tashxii/items/3195157e5e82d3790afd)

#サマリ
Reactの使い方に慣れ、リッチなコンポーネントを使ってElectronアプリケーションをよりモダンにしようというテーマです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180351/beac3ab9-4edd-21a5-8465-63973e8c2ab3.png)

レトロなElectronアプリケーションを前提知識の少ない状態からReact+Reduxを使って
どう作るかは、[こちらの記事](http://qiita.com/tashxii/items/290a3421d520bdae0c36)で触れていますのでご参考までに。
今後はこれをよりモダンにしたいです。


##Reactのコンポーネント
**リッチなコンポーネントを選んで使える**
Reactでは誰かが作ったり、自分で作ったコンポーネントが再利用できます。
「react best ui library」などで検索すると参考になるページがヒットします。
５つのサイトで紹介されているものの一覧表も作ってみました。
[そちらの記事](http://qiita.com/tashxii/items/6e3e25e8b0f690570920)も参照ください。

このあたりが気になるところです。上の画像はデモからコンポーネントを切り出したものです。
- Material UI http://www.material-ui.com/
- Elemental-UI http://elemental-ui.com/
- React-Bootstrap https://react-bootstrap.github.io/
- grommet https://grommet.github.io/
- Ant Design http://beta.ant.design/docs/react/introduce
- Office fabric  https://dev.office.com/fabric#/

**リッチなコンポーネントを自作できる**
公開されているコンポーネントを参考に作成することができます。
ただ、個人的には、いきなりスクラッチからコンポーネントを自作するのはデザイナや多くのリソースを抱える専門の組織や団体には負けると思います。まず自作より便利なものを利用して、その便利さをどう使うか、どう作るかを学ぶほうが最終的な成果は高いと思います。

#ReactとReduxの概要
##Reactとは
*「A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACES」*と
公式ページ https://facebook.github.io/react/ に書かれているように、UIを構築するViewを担当するJavaScriptのライブラリ（≠フレームワーク）です。過去の記事でフレームワークと言っていたかもしれませんが訂正させていただきます。
アーキテクチャはFluxという名前で、Fluxを実装したフレームワークの一つがReduxです。

###３つのコンセプト(昔のHPの画像や解説から)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180351/29e0890f-0dcc-0117-7da2-d6a085fb7a83.png)
英語を意訳すると下のような感じです。

- JUST THE UI （UIだけ）   
   *「Reactは多くの開発者にMVCのViewだけに使用されています。Reactは残りの技術に関しては何も前提としないため、既存のプロジェクトに試験的に小さな機能を導入するのは容易です。」*
  - Viewに特化したライブラリで、MとCには無関係なので、既存アプリに簡単に取り込むことができます。
- VIRTUAL DOM  （仮想DOM）    
  *「ReactはDOMを抽象化することで、簡単なプログラミングモデルと優れたパフォーマンスを提供します。ReactはNodeを使ってサーバーでレンダリングすることもでき、React Nativeを使ってパワフルなアプリケーションを作ることもできます。」*
  - DOMを抽象化してメモリ上に展開しているので、後述のJSXを使った簡単な実装と、レンダリングも変更した差分だけ更新するので、パフォーマンスに優れます。
  - Nodeを使ってサーバーで描画させたり、React Nativeを使ってNaitiveなアプリと同等のパフォーマンスを持つアプリケーションを作ることができます。
  - この辺りの解説は、[「一人React.js Advent Calendar 2014」](http://qiita.com/advent-calendar/2014/reactjs)の、[Qiita-](http://qiita.com/koba04/items/fd6d9f24f9f6ce50e47e)に書かれています。25日分の半分くらい読みあさりました。あと半分は来週の課題です。
  - [Qiita-なぜ仮想DOMという概念が俺達の魂を震えさせるのか](http://qiita.com/mizchi/items/4d25bc26def1719d52e6)で熱く語られています。
- DATA FLOW    
   *「Reactは一方向のデータフローを使ってプログラミングから定型的な実装を減らし、古典的なデータバインディングより状態を簡単に予測しやすくします。」*
  - Action（ユーザーの入力）→Dispatcher（イベントの発行）→Store（イベントで受動的に変化する状態＝片方向だけの自動的なデータバインディング）→View（状態の表示）→Actionと一方向のループなので、双方向データバインディングや、M<->Cの関係（「ある一定の数値以上ならViewの背景を赤くする」といったMでもCでもない境界があいまいになるプレゼンテーションロジック）を無くして実装を軽量化し状態の把握や予測を簡単にします。

###３つのコンセプト(今のHPの記述から)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180351/72141544-cd28-7bc0-de05-a2ae07a6ff0e.png)
恣意的に意訳すると以下のような感じです。

- Declarative （宣言的）  
   *「Reactは対話形式のUIを作成することを容易にします。アプリケーションでの各データの状態に対して宣言的にシンプルなViewを設計してください。Reactは、データの状態変更に応じて正しいコンポーネントだけを更新、描画します。宣言的に書かれたデータに対応したViewはコードを予測しやすくデバッグを簡単にします。」*  
  （２文目がリアクティブなので、Reactという名前なんでしょうか）
  - 開発者が描画するデータに対応した部分だけのシンプルなViewを設計しておけば、Reactが適切にデータの状態に応じてViewを更新してくれます。
  - データに対して対応する部分だけを宣言的に書かれたViewを作ることで開発は簡単になります。
- Component-Based （コンポーネントベース）  
   *「独立した状態だけを管理するUI部品を作成してから、それらを含む複雑なUIを作成します。コンポーネントの（描画の）ロジックは（HTMLの）テンプレートではなくJavaScriptの中に（その他のイベントハンドラ等のロジックの近くに）書かれているから、リッチなデータをアプリケーションに持たせることが簡単にでき、DOMから状態を守ることができます。」*
  - HTMLとJavaScriptに分離して描くのではなくUI部品に対応するJavaScriptで描画ロジックを書くので、状態の分離を簡単化できます。
  - DOMを使ってHTMLの描画ロジックを書かないように、状態からDOMをKeep out（立ち入り禁止）にできます。（ここの意訳は正しいかどうか自信はありません。）
- Learn Once, Write Anywhere （一度学べば、どこでも使える＝学習のコストが低い）  
  *「We don't make assumptions about the rest of your technology stack, so you can develop new features in React without rewriting existing code. React can also render on the server using Node and power mobile apps using React Native.」*
  - 昔のコンセプトの「VIRTUAL DOM」とだいたい同じことを書いてますので省略。

個人的には昔のコンセプトのほうがより端的な特徴を書いているように思えます。

###JSXとは
- HTMLに似たタグをJavaScript内のrenderメソッド内で書けます。
- DOMを使った書き方より直感的に書けます。
- その代わりJavaScriptになるようトランスパイルが必要です。
- トランスパイラはBabelといってFacebookの公式ページでReactのインストールの説明のところに記述されています。
- JSXを使わないでもReactは動きますが、使うメリットは大きいと思います。  
  この辺りも、「一人React.js Advent Calendar 2014」の、[Qiita-React.jsのJSXを使ってみる](http://qiita.com/koba04/items/039b9c974df284766f64)に書かれています。印象的な部分だけ抜粋します。

```:JSXの記述例
var Hello = React.createClass({
  render: function() {
    return (
      <div>Hello {this.props.name}</div>
    );
  }
})
```

```:DOMを使う場合とJSXを使う場合の比較
・JSXを使うことでHTMLに近い感じで記述出来て非エンジニアにもわかりやすいメリットがあります。
　・好みもあるかと思いますが、React.DOM.div(null, 'hello')よりは<div>hello</div>の方が...
```
##Fluxとは
*「An application architecture for React utilizing a unidirectional data flow.」*と、
公式ページ https://github.com/facebook/flux に書かれています。
Reactのための一方向のデータフローを実用化したアーキテクチャです。

実装は、オレオレ実装や企業が実装したものなどがあるらしいです。
「一人React.js Advent Calendar 2014」の[Qiita-React.jsとFluxのここ](http://qiita.com/koba04/items/b32ba449d753fdb2b597#%E3%81%9D%E3%81%AE%E4%BB%96%E3%81%AEflux%E5%AE%9F%E8%A3%85)を参照してください。
記事は古いので現状は調べていません。

Fluxは、FacebookがMVCの採用を止める時に考えたアーキテクチャです。
止める経緯やMVCとの比較は以下を参照ください。

- [Facebook の決断：MVCはスケールしない。ならば Flux だ。](https://www.infoq.com/jp/news/2014/05/facebook-mvc-flux)  
  MVCを誤用しているという記述はありますが、ただ違うフレームワークでどちらが特に悪いというものではないと思います。
- MVCとの比較は次のページの図がわかりやすいです。[Qiita-Fluxとはなんなのか](http://qiita.com/knhr__/items/5fec7571dab80e2dcd92)

解説は後で図を付けて行います。

##Reduxとは
Fluxを実装したフレームワークです。
次のページとその関連ページに詳しい内容が載っています。

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

以下の用語とそれらの関連を理解する必要があります。
超ダイジェストで書くと以下になります。具体的な解説は別記事で行いたいと思います。

- Storeとstate(とprops)  
  アプリで管理する状態の箱と、画面ごとに持つ状態。
- Componetns 
  stateに対応した画面部品。Reduxはstateが変化すると描画を自動で行う。
- Action(とActionCenter)  
  イベントの定義とその箱。イベントは状態を遷移させるパラメータを持つ。
- DispatcherとContainer
  ユーザーの入力とactionを関連付けと、それによって更新されるべき画面の関連付けを行う。
- Reducers
  状態を遷移させるピュアな関数群。Containerで関連付けたstateとDispatcherが送出したactionを受けて新しいstateを返す。stateが更新されると対応した画面は自動で更新される。

解説は後で動く図を付けて行います。
上の説明は私も一回で理解できなかったので流していただいて構いません。
Containerが初見ではイミフです。

###３つの原則
Reduxの３原則です。例によって意訳します。
http://redux.js.org/docs/introduction/ThreePrinciples.html に書かれれています。

- Single source of truth  状態の箱はアプリで１つ  
  *"The state of your whole application is stored in an object tree within a single store.”*  
  「状態の箱である Store はアプリケーションで１つにするべきだ。」
- State is read-only 画面の状態は読み取り専用  
  *"The only way to change the state is to emit an action, an object describing what happened.”*  
  「画面で純粋に描画するstateは読み取り専用で途中で更新してはならない。actionが起きたときだけstateは状態遷移関数であるreducersで新たに作成して返されるべきである。」
- Changes are made with pure functions  状態遷移はピュアな関数でされる  
  *"To specify how the state tree is transformed by actions, you write pure reducers.”*  
  「actionによって画面に描画される前のstateを、更新する状態遷移関数はピュアであるべきだ。」

これもすぐ下で図解します。

#FluxとReactとReduxのアーキテクチャの図解
図は公式の外部サイトを直接貼っているため、将来Not Foundになるかもしれません。
GitHubなのでその可能性は低いですが、その際はお手数ですがコメントください。

##Flux
以下が公式ページと解説です。
http://facebook.github.io/flux/docs/in-depth-overview.html
http://dialelo.github.io/application-architecture-with-react-rethinking-flux.html

Fluxの図 https://facebook.github.io/flux/docs/in-depth-overview.html#content
![Fluxの図](https://facebook.github.io/flux/img/flux-simple-f8-diagram-explained-1300w.png)

1. Actionは状態を変えるパラメータを持つ
2. Dispatcherは、ユーザーの入力イベントでactionを飛ばす。
3. Storeは、actionで前の状態から最新の状態に変えられる。
4. Viewは自動的に描画する。その後またユーザーの入力イベントで1.に一方向でループする。

##React
以下がFluxに関するFacebookのブログです。
https://facebook.github.io/react/blog/2014/07/30/flux-actions-and-the-dispatcher.html

Reactを使ったアプリケーションの図
![Reactを使ったアプリケーションの図](https://facebook.github.io/react/img/blog/flux-diagram.png)

1. Web API, Web API Util ... ユーザーの入力を受けるフロントエンドアプリ
2. ActionCreator,Action ... ただのイベントの箱（発火されていない）
3. Dispatcher, Callback ... アクション後に呼ばれる関数を渡しつつアクションを発火する。
4. Store, Change Events + Store Queries ... アクションに対応した状態を遷移させる。
5. React View ... 状態の遷移に対してリアクティブ（受動的＝オブザーバー的）に画面を更新する。
6. User Interaction ... ユーザー入力で、2.へループ。2-6が一方向になっている。

##Redux
Reduxの公式ページには、画像は少ないです。
以下のページに画像集があるので、それを引用します。他の図に興味があれば１番目のサイトを参照ください。

https://github.com/reactjs/redux/issues/653

![reduxの振る舞意を表す図](https://camo.githubusercontent.com/5aba89b6daab934631adffc1f301d17bb273268b/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6d656469612d702e736c69642e65732f75706c6f6164732f3336343831322f696d616765732f323438343535322f415243482d5265647578322d7265616c2e676966)
このGIFが一番分かりやすいと思います。

1. 画面でボタンが押されると、
2. Actionが作られ、
3. Dispatcherによって関係する状態遷移関数reducersが呼ばれ、
4. Storeから、前のstateと、actionをセットに、新しいstateが作られ、
5. 画面が再描画されます。

この図が含まれるスライドです。 
http://slides.com/jenyaterpil/redux-from-twitter-hype-to-production#/9

#さいごに
参考にさせてもらったサイトや記事には感謝しています。
またここまで読んでいただけてありがとうございました。

有識者から見て間違い等あれば、指摘のほどよろしくお願いします。
まだまだ来週以降も続けたいと思います。

##これまでのヒストリー
###今週までにやったこと/やってないこと
┳ ○ Electronの概要を知る
┣ ○ Hello Worldを作る
┣ ○ とにかく動くサンプルをコピーする
┣ ○ Electronの仕組みを最低限学ぶ
　　　→ [ElectronのインストールからHello Worldまで](http://qiita.com/tashxii/items/0d0de88249bde75ac802) にまとめました。
┣ △ IDE(開発環境、デバッグ環境)を揃える (Electron IDEでググる)
┃　→ [HTML5開発に適したIDEを探す（その9）](https://blog.htmlhifive.com/2015/06/09/visual-studio-code/)を参考に選定します。
　　　→ IDEは今はとりあえず、Visual Studio Codeにしています。
┣ ✖ ビルドを自動化する (electron ビルドでググる)
┣ ✖ テストを自動化する
　　　→ ビルドとテストはまだです。ロジック層がまだないためです。
┣ △ Explorerを作ってみよう
┃　　┣ ○ JavaでのPrimefaces, Richfacesのようなコンポーネントがあるといいな。
┃　　┃ → React, Flux, Reduxというキーワードが散見。
　　　→ エクスプローラーのプロトタイプを作成しました。
　　　[Electron+React+Reduxで作るレトロなエクスプローラのハンズオン(チュートリアル)](http://qiita.com/tashxii/items/290a3421d520bdae0c36)
┣ ✖ 例外設計を知る
┣ ✖ 国際化対応を知る
　　　→ 例外、国際化とも未着手