JavaScript

1から学ぶReact-Redux

投稿日:2018年7月14日 更新日:

React-Reduxとは

React.jsは、バーチャルDOMという考え方で表現できるJavascriptのライブラリで、差分描画をするので全部のDOMを書き換えるより高速に描画することができる.基本的に表示用のライブラリ.
Reduxは、デザインパターンの一つオブザーバーパターンの一種、そして、これを実装したJavascriptのライブラリ.
React-Reduxは、React.jsでReduxを使えるようにするJavaScriptのライブラリ.

今回は、勉強のためにシンプルな電卓をつくってみた.

create-react-app

create-react-appは、Facebookが提供するオールインワンのReact.jsのアプリの開発環境.サーバーはもちろん、webpackの設定まで揃っていて、すぐにReact.jsの開発に着手できる.

アプリのディレクトリを作るには、下のコマンド.
これで、現在のディレクトリの直下に入力した名前のディレクトリが作成される.

開発用のサーバのスタート.
これで、ブラウザも自動で開かれるはず.

git initはされないので、最初にしておいたほうがいい.

電卓のロジック

保存するデータはとりあえず3つ.
まず、数字を押すと1桁目に数字がたされていく場所.これをbufferとする.
次に、+ーなどの演算子が押されたら、数字として認識して保存する.これをtotalとする.
また、その際、押された演算子も記憶しておき、bufferをクリアにする.これをstackedOperatorとする.
最後に、bufferに数字を入力し、=を押すと、totalとbufferでstackedOperatorで計算して、bufferに結果を表示する.

以下は、初期値.

reactで電卓の外観を作る

外観は、buffer、total、stackedOperatorの表示場所を作成し、そして、ボタンを作成する.

今回、material-uiをつかった.

最初のindex.jsとApp.jsを生かして、次のようにステートレスコンポーネントを作った.
ステートレスコンポーネントは、propsとJSXだけの関数でつくるシンプルなコンポーネント.
ちなみに、classは、export default classができるけど、export default constは許されてないので、別途export文を書く必要がある.結構忘れがち.
バーチャルDOMには好きなプロパティを与えることができて、コンポーネント内ではpropsから取得することができる.
そして、なるべくコンポーネントは描画だけに特化するべきであり、なるべくステートは持たないようにするというjQueryからの発想の転換が必要.

リストとかマップとか使うべきだけど、後からいろいろアクションをつけるので、コピペでボタンを並べた.

これで簡単に計算機の外観ができた.ボタンをクリックするとログに表示されるだけ.

reduxでとりあえずのロジックを作る

Appの外側に設定するので、とりあえずindex.jsでreduxを試してみる.

storeは、stateとreducerからできているオブジェクト.
そして、store.dispatchでイベントが起きたときに、reducerに従ってstateを更新することができる.reducerはcombineReducerで組み合わせることもできる.
また、store.subscribeでdispatchを監視することができる.
そのほか、ミドルウェアをかませて、何かの処理を挟むこともできる.
これがreduxライブラリのほぼ全容.

電卓の場合は、こんな感じ.
reducerは、stateとactionを受け取ってstateを返す関数で、内部では、action.typeにしたがってswitchすることが多い.
数字ボタンが入力されたら、0の場合を除いて、後ろに付けたす.0の場合は上書きする.
…storeは、たぶんECMAScriptの機能で、配列を展開するという意味.つまり、この場合は前と同じ数値を入れる.
そして、書き換える部分だけ後ろに書く.すると、後から書いたほうが有効になる.
全部書き換えると思っても、後からstateの要素が増えることもあるので、とりあえず書いておいたほうがいいらしい.

すると、コンソールには、次のとおり表示される.
store.dispatchでイベントが発火して、reducerがstateを書き換えて、その内容をsubscribeしてコンソールに表示しているという仕組み.

さらに、便利なミドルウェアの1つとして、redux-loggerがあって、これを使うとdispatchイベントの前後をlogでカラフルに表示してくれる.

とりあえず計算機のreducerを適当に実装する.

react-reduxでpropsとdispatcherをコンポーネントに配置する

react-reduxで提供するのは、reduxのステートをコンポーネントに伝える機能とdispatchを配置する機能.

App全体をProviderコンポーネントでくくり、storeを渡す.

そして、Provider以下で、connect関数をexportする.これでOK.

これで、Appのpropsとして、定義したprops.bufferやprops.handleNumberにアクセスできるようになる.
{…props}とすることで、そのまま下のコンポーネントにpropsを渡すことができる.

テスト Jest & Enzyme

create-react-appには、テストランナーもついてる.
それがjest.
jasmine2の後継ぽい.

yarn test でテストランナーが走る.

そして、コンポーネントのテストには、Enzymeというライブラリを使う.AirBnb製.

コンポーネントのテスト

コンポーネントは単体の関数のはずなので、個別にテストできるはず.
shallowというメソッドでモックを作ってテストする.
テストはSPEC系の書き方.describeからitでexpect.

propsをわたす場合

setPropsでOK.

reducerのテスト

reducerは純粋な関数だから簡単.まず、reducerを別ファイルにしてexportしておく.
reducerは、stateとactionを引数に取るから、stateとactionを与えて、返り値をテストすればよい.

redux-devtools-extention

redux開発用のChromeエクステンション.stateの状態とかactionの履歴とかわかって便利.

まず、Chrome Web Storeからredux-devtools-extentionをインストールする.

つぎに、storeの設定をする.composeというライブラリをreduxからインポートする.
で、applyMiddlewareをラップする.

redux-devtools-extentionでは、reducerのテストも自動で書ける.
テストテンプレートの追加がなぜか機能しないので、Jestのテンプレートを編集する.

で、最後に送ったActionとStateでこんな感じのテストを書いてくれる.

最後に送ったActionだけじゃなくて、左のActionを選ぶこともできる.
シフトで複数選択も可.

カバレッジ

jestではカバレッジの確認も簡単.

reduxのディレクトリ構造

例えば、react_on_railsのreduxでのディレクトリ構造は、こんな感じ.

まず、packsからstartupのファイルを読みに行く.ここではcontainerのAppをProviderでくくるだけ.
storeは、store以下から読み出す.

次に、containerのAppをみると、ここではreduxのconnectをするだけ.
逆に、こういうconnectするだけのファイルをContainerと呼ぶ.
actionは、action以下のactionCreaterから読み出す.
そして、actionタイプは、constants以下で定義づけている.

最後に、Reactのコンポーネントは、components以下に書かれてる.

デプロイ

buildディレクトリ以下に、プロダクション用のファイルが作成される.

説明文にも出てくるように、serveで中身を確認できる.

-JavaScript
-,

執筆者:

関連記事

no image

Rails3で動画配信を試用~flowplayer

  最近はYoutubeなど動画配信サイトも充実してきていて知人向けのプライベートな配信も可能なようだ しかし、やっぱりYoutubeにアップするのは抵抗があったり、LAN内だけで配信したい …

Rails4でMarkdownをリアルタイムプレビュー〜vue.js&marked.js

By: Matthew Wilkinson – CC BY 2.0 目次1 vue.jsとは2 Hello vue.js3 サンプル準備〜Redcarpet導入など4 vue.jsでリアル …

Rails4でのJavaScriptのユニットテスト~jasminerice&guard-jasmine

By: sk_vel – CC BY 2.0 Rails3.2でJasmineをつかってCoffeeScriptをテスト~jasminerice 目次1 環境2 Gemfile3 gene …

vimでcoffee scriptの開発環境を整える~vim-coffee-script

環境 CentOS5.8にnodebrewでnode.jsをインストールを参考にubuntu server 12.04にnode v0.6.20をインストールした 目次1 coffee scriptの …

Rubyでd3.jsのapiリファレンスの一覧を取得してくる~mechanize

  d3.jsにはlayoutというおおまかに準備されたレイアウトがあって、その中にあるTreeレイアウトを試してみることにした d3.js自身のapiリファレンスが階層構造になっているので …