React,Reduxのキャッチアップ

フロントエンド周りの技術が少し落ち着いてきたという風潮があるので、キャッチアップ。

やったこと

React自体は結構シンプルでわかりやすく、メリットも感じられた。 state周りが、fluxの予備知識が少しあったので、reduxとどのように組み合わせるのかなというのはモヤっとしたけど、一旦放置。

【翻訳】あなたが求めていたリアクティブプログラミング入門 - ninjinkun's diary

いい記事だと聞いていたので見てみた。 ぼんやりと理解。

  • Redux video course

Getting Started with Redux - Course by @dan_abramov @eggheadio

公式ページの上部に紹介されていたので、英語のリスニング練習も兼ねて見てみた。

TodoListの完成まで(1/3ぐらい?)見てなんとなく雰囲気がわかってきたので一旦停止して、自分で書いてみることに。

Todoアプリを書いてみる

  • 準備

npm init and install react, react-dom, babel-*

  • webpack 設定 appsとvendorを分けるように設定した。
var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: {
    main: './main.jsx',
    vendor: ['react', 'react-dom', 'react-addons']
  },
  output: { path: __dirname, filename: 'bundle.js' },
  module: {
    loaders: [
      {
        test: /.jsx?$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        query: {
          presets: ['es2015', 'react']
        }
      }
    ]
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin(/* chunkName= */"vendor", /* filename= */"vendor.bundle.js")
  ],
  devServer: {
  }
}
  • サーバー通信なしで機能させる

    • reducerにstateを定義
    • actionを定義
    • component作成
    • storeを作成
    • react-reduxのProviderでstoreとcomponentを連携

わからないところは、

Basics | Redux

を見ながら実装。

サーバー連携

サーバー連携のAsync処理はいくつか方法が紹介されていたので少し混乱。

まず単純にaction周りにjQueryAjax処理を書いて機能させてみた。

次にredux-thunkでaction creatorの慣習に従ってAjax処理を呼び出せるように調整

GitHub - gaearon/redux-thunk: Thunk middleware for Redux

次に jQuery Ajaxをfetchに置き換えて完了。

GitHub - matthew-andrews/isomorphic-fetch: Isomorphic WHATWG Fetch API, for Node & Browserify

サーバーサイドはrailsで作成した。

感想

reactコンポーネントは考え方もシンプルで、APIも少なく、分かりやすい。 stateの移行や、data flowが絡むと複雑になる。

ReactComponent.stateやreduxのconnectなど、また手動でもできるということで、すっと理解するのが難しい。

react-reduxのconnect, Providerを使うとこの辺りの関係がすっきりする。

この程度の規模のコードならスッキリ書けるけど、プロダクトレベルになった時にどうなるのか、どのように管理していくかが解らない。

componentsは整理できそうだけど、actions, reducersあたりがだいぶ複雑になりそう。

ということで次の課題は、 Recipes | Redux を読んでみるのと、もう少し複雑なものを自分で作ってみる?

メモ

react-redux connect

componentのpropsにstoreと連携するためのオブジェクトを設定できる。

引数なし: React.component.props.dispatchにstore.dispatchが入る。

mapStateToProps: stateからpropsへマージされるデータを生成する。pure function.

mapDispatchToProps: store.dispatchを受け取り、propsへマージされる、dispatch処理を含んだ関数を生成する。

Providerはstoreとchild compnentをconnectを通じて連携させる。


react-thunk

store.dispatch() にfunctionを指定できるようにするmiddleware

returnするfunctionにはdispatch, getStateが引数として取れるので、asyncプロスセのcallback等でdispatchを呼び出すことができる。

asyncの処理を含むaction creatorを他のaction creatorと同じように呼び出せることがメリット?


fetchでpostする際の注意点

fetch https://github.com/github/fetch

form data でPOSTする際。 http://stackoverflow.com/questions/29775797/fetch-post-json-data

json形式でpostする際。 http://jxck.hatenablog.com/entry/whatwg-fetch

railsでscaffoldされたController#createメソッドはform形式で送信される想定で実装されているので、jsonで受け取る場合は修正する必要がある。 http://masawada.hatenablog.jp/entry/2015/12/29/195317


Reactコンポーネントでのformの値の扱い方

linked state mixin https://facebook.github.io/react/docs/two-way-binding-helpers.html deprecated

https://facebook.github.io/react/blog/2016/04/07/react-v15.html linkedStateMixinはdeprecatedなので、stateのchangeをhandleする関数を自作するのが推奨?