Redux について思う事
あらすじ
最近 React 案件の商談が多いのですが「Redux で書かれたビジネスロジックのテストもお願いしたい」とか言われて、んん?となったのでなんとなくブログにします。
ビジネスロジック と Redux が混在する?何故?
Redux はおおざっぱにいうと以下の概念で動きます。
Actions -> Reducers -> Store
そして Redux の3原則は以下のとおり
- Single source of truth
- State is read-only
- Changes are made with pure functions
そう、Redux は基本的に pure function を使います。そして pure function は以下のような関数の事です
function square(x) { return x * x; } function squareAll(items) { return items.map(square); }
そして以下は pure function ではないです。
function square(x) { updateXInDatabase(x); return x * x; } function suareAll(items) { for (let i = 0; i < items.length; i++) { items[i] = square(items[i]); } }
これは作者が動画で説明しています
https://egghead.io/lessons/react-redux-pure-and-impure-functions
pure function だと何がどれぐらいうれしいのか、という話は私はあまり関心がないので気になる方はリンク先の動画をたくさんご覧ください。
いずれにせよ reducer も action も pure function になると私は思っているので「Redux で書かれたビジネスロジック」と言われてもピンとこない。私の解釈だとビジネスロジックは Action の前で実行を終えているはず。
[Bussiness Logic] -> [Actions -> Reducers -> Store]
なので Bussiness Logic は分離してテストを書けば良いのではないかなあと思うわけです。つまり actions.js
には pure function だけを書く。
ただし、私の考えが公式サイトの Tutorial とそぐわない
公式サイトにある Async function の Tutorial には fetchPosts という関数が actions.js に書かれています。
https://redux.js.org/advanced/async-actions
そもそも非同期処理は pure function なのか?
そもそも非同期処理は Pure function ではないはず。なのでそれを dispatch するのは問題なのではないかなあと思います。非同期処理が終わってから結果を dispatch すればいいはず。なんですがそれをせずに middleware で Redux の非同期処理については私は疑問があります。似た考え方をする人もいるようですし
React+Reduxで簡単な勉強会イベント検索アプリを作って公開してみる - Qiita
そうでない方もいると思います。
Reduxのmiddlewareを積極的に使っていく - Qiita
メリットとデメリットの捉え方が人それぞれだし状況も違うのでどちらが優れているとも思いませんが、この辺りって2018年現在ではどのような論調になってるんでしょう?
redux-saga
私が redux を使わないで Single Page Application を作る Tutorial - Qiita を書いたのはこれがきっかけです。どうしても redux-saga
とはそりが合いませんでした。
もしかすると冒頭の「Redux で書かれたビジネスロジックのテストもお願いしたい」というのは redux-saga
の事だったのかなあ?それはいやだなあ。
もちろんメリットがあるのであれば頑張りますが、物事を複雑にしがちだし、対して得られる恩恵が少なそう、というのが私の redux-saga に対する見解です。こういう事書くと使いこなせいお前が悪い、という話にもなりそうですがそう思って頂いて結構です。
まとめ
そんなわけで Redux はすごくシンプルなのでミニマリスト志向な私はとても好きな概念なんですが非同期処理とかビジネスロジックとかがやってきて私の好きな Redux で無くなるのがいや、そんな感じ。