RTK Listener Middlewareについて
RTK の v1.8 にて新しく Listener Middleware が追加される。これについて考えとかを整理しておく
Middlewareについて
いままでは、RTKにおけるMiddlewareはThunk 一択だったが、今回新しくListenerという形のものが追加された。
これは雑に言うと Observable/Saga な感じでMiddlewareが書けるようになるというもの。
いままでのThunkは、既存のactionをラップする形のMiddlewareだった。
Listener だと、下記のようなことが出来るようになる。
- ActionをListenしてCallbackを発火
- Stateの変更を検知してCallbackを発火
特に2つ目ののListenはReact.useEffectと同じような考えになる。
依存関係
Thunkとは逆の矢印で依存関係を構築できるようになると思う。
そのため、使いどころによってはListenerのほうが刺さる箇所がありそう。
例えば、ログ系はThunkじゃなくてListenerのほうが良さそう。
懸念点
問題なのはThunk・Listenerのどっちを使うのかの線引が明確にできない点。
どちらでも実装できるので、実装者が各々の判断でどちらで実現するかを考えることになる。
そのため、2つの種類のmiddlewareが入り交じる。
特にListenerは下手に使うとListen地獄になりそうで怖い。
なのでひとまずは、シンプルに徹してthunk一択にするのでもいい気もしてる
設計
listener は observable / saga から来ているので、プラクティスについてはobseravable / saga のコミュニティが持っている設計指針とかを知るのが良さそう。個人的には、これらを使ったことがないのであまりわからないが。
Idiomatic Redux: Designing the Redux Toolkit Listener Middleware · Mark's Dev Blog
- RTK / Redux のメンテナーによる解説
- 序盤にある「なぜこれを入れた」系の内容を読むと背景が理解できてよかった
TODO: 手元で小さめに動かしてみたい
TODO: プロダクトに導入してみたい
RTK Query にて Listener
RTKにおいてのListenerはドキュメントにある通りだけど RTK Query でListenerに近い動きをさせたい要件が出てきたので調べてみた。
結論、Listenerとしては提供されてないみたいだけど、baseQueryの中でcallback/dispatchを発火できるのでこれで実現するのが良いみたい。
Listen on any API Request (RTK Query) · Issue #1956 · reduxjs/redux-toolkit · GitHub
ただ、ややHackな方法としてListnerでもできそう。
Listenerでlistenするときにaction名をstringで明示できて、かつRTKQは内部的にはRTKでつまりActionが発火されてる。なので、この組み合わせでやればRTKQをListenできそう。
// https://redux-toolkit.js.org/api/createListenerMiddleware#startlistening
listenerMiddleware.startListening({ type: 'todos/todoAdded', effect })