Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Should I use redux-saga or not?

Yuki Kodama
September 27, 2016

Should I use redux-saga or not?

redux-sagaの解説、ReduxのMiddleware選定のお話、最近注目のMiddlewareの紹介をしました。デファクトは定まる気配がありません。

Yuki Kodama

September 27, 2016
Tweet

More Decks by Yuki Kodama

Other Decks in Technology

Transcript

  1. Should I use redux-saga or not? @kuy / Yuki Kodama

    2016.09.27 @ React.js meetup #4
  2. 自己紹介 @kuy (カイ) / Yuki Kodama 株式会社ジャパンベンチャーリサーチ entrepedia(アントレペディア)の開発・運用 AWS, Ruby

    on Rails, JavaScript (React + Redux) • redux-sagaで非同期処理と戦う • Reduxでコンポーネントを再利用する • Reduxのmiddlewareを積極的に使っていく • ・・・など Qiita の記事 発表 • なぜReduxを使うのか
  3. redux-saga というのは • Redux の Middleware • React にも Redux

    にも書きたくないコードを置く場所を提供 • generator/yield によって非同期処理を同期処理として書ける • あらゆる副作用をデータとして扱える ◦ 強制されるわけではない • ギリギリまでモックを使わないテストが可能 ◦ モック不要とは言ってない サンプルあるよ! https://github.com/kuy/redux-saga-examples
  4. redux-saga 登場人物 Effect を使って処理を書く • Saga: 実行したい処理をまとめたプロセ スのようなもの • Effect:

    データとしての副作用 • Saga Runtime: 実行環境 • Effect を yield で返す Generator 関数 • Saga Runtime が Effect を実行 • 内部的には状態マシンになってる • call: (非)同期関数呼び出し • select: 状態の取得する • put: Actionのdispatch • take: Actionを待ち受ける • fork: 別の Saga を起動する • cancel: 起動した Saga を中止する • ....などなど redux-saga が提供する実行環境で Saga を起動する 実装
  5. redux-saga の挙動( call ) var eff = mySaga.next(); var ret

    = yield call(hoge, 10); [1] ... = mySaga.next() [2] ... = yield call(hoge, 10) [3] var eff = ... hoge(10).then(ret => ...) mySaga.next(ret) [4] var ret = ... Saga Runtime Your Saga e.g. (pseudo) “call” effect object { fn: hoge, args: [10] }
  6. redux-saga の挙動( select ) var eff = mySaga.next(); var data

    = yield select(foo); [1] ... = mySaga.next() [2] ... = yield select(foo) [3] var eff = ... var data = foo(getState()) mySaga.next(data) [4] var data = ... Saga Runtime Your Saga e.g. (pseudo) “select” effect object { fn: foo }
  7. redux-saga のコードが増えてきたら • 適切に分割する ◦ 単一責務を意識する ◦ 例:あるActionを受け取ったら別のActionをdispatchして画面遷移する →ActionをチェインさせるsagaとActionを受け取ったら画面遷移するsagaを独 立して動作させる

    • 共通のsagaを切り出す • 変化の少ないソリッドな処理はMiddlewareで書く ◦ Socket.IO、Firebaseの連携など • あくまでもsagaはロジックを書く場所にしておく • 他で書けない/書きたくないものをsagaで書く • ・・・詳しく知りたい部分があったら直接聞いて下さい! → @kuy or リアル
  8. redux-saga の問題点 • 基本的に初見殺し • 学習・導入コストが小さくない • generator/yield が必須 ◦

    regeneratorRuntime によってスタックトレースが死ぬ • 隠しきれないコード中の yield の存在感 • dispatch された Action を reject できない 他の Middleware はどうなんだろう?
  9. redux-saga redux-loop redux-machine redux-api-middleware redux-observable redux-thunk redux-promise redux-effects redux-task redux-logic

    Side Effect 関連の Middleware 多すぎ・・・ 全部見たい人→ https://github.com/markerikson/redux-ecosystem-links/blob/master/side-effects.md
  10. Side Effect Middleware に求めているもの • Scalability + Composability ◦ 適切にコードを分割できる、共通化しやすい

    ◦ 全体を知らなくても、部分的な理解でメンテ可能 • Testability ◦ 本当にテストしたい部分だけテストコードを書ける • Background/Long-Running Process ◦ UIコードと完全分離したい
  11. redux-logic(まだ実戦投入してない ) ✅ 第一印象:Middleware を構造化してくれる Middleware、内部はRxJS ✅ 副作用コードを validate, transform,

    process の3つに分ける redux-sagaで不可能だったActionの reject が可能! ✅ 好みの方法でロジックを書ける vanilla, RxJS, async/await 処理によって得意分野が違うから、書き分けするのもあり? ✅ サービスがDIされるので比較的テストしやすい(はず) けど、モックは避けられない・・・? ❌ 副作用をデータとして扱っているわけではない 要調査: async/awaitを使った場合のテストは? "I wrote the rxjs code so you won't have to." by @jeffbski
  12. さらに続く期待の新人たち・・・ • clarus/redux-ship (redux-sagaの正統進化系になりえる?) ◦ Composable, typable and testable Redux

    middleware • exponentjs/redux-effex ◦ Spin off async functions to perform side effects どちらも副作用をデータとして扱っている
  13. React.js + Redux + redux-saga React.js Redux View State Side

    Effect redux-saga Middleware 理想的な Side Effect Middleware とは?
  14. redux-observable • Netflixが開発、RxJS 5.x • Epicの導入によってアクの強さが軽減された • 副作用をデータとして扱ってない ◦ →

    テストのしやすさの観点ではイマイチ • RxJS知らないのにわざわざ勉強してまで使うメリットは感じられなかった • RxJSをすでに知っているか、RxJSが大活躍するロジックをたくさん書く なら選択肢に含める、くらいの感じ
  15. redux-saga 以外の選択肢 • redux-thunk • redux-promise • redux-observable • redux-loop

    • ...etc @shuheikagawa https://speakerdeck.com/shuhei/redux-middleware-wars-japanese