さよならnormalizr
2019/09/25
主題: もうnormalizr使うこと無さそう
Redux
主となる役割は状態管理である。
DBのデータは広義には状態の一つと言える。だが狭義に考えると状態と言うべきか?
DBの値はあくまでread-only
writeすることはあるにしても、あくまでserverへ書き込みをし、結果をまたreadデータとして更新するになるのでは?
例えば返り値を使わずにステータスだけでwrite後にreadを更新する、というにもあるにはあるが。結構やるとつらい
この記事で言うとDataの部分の話。今回はこの用語を利用する。
現実
DBのデータは読み取り専用。またそうあるべきはず
「下書き状態」みたいなのがあるとちょっと違うかもしれない
実質キャッシュみたいな状況になってる
通信のためにmiddlewareが必要になりがち
hooksの場合、発火点だけuseEffectにしてmiddlewareナシというのは可能だけど。
DBは読み取り専用
ざっくり言うと読み取る機能と、reloadするような機能さえあればほとんどの要件を満たす。
例えば満たさない場合はそれだとパフォーマンスに問題がある場合など
通信状態は?
組み方によるが、コンポーネント単位でSpinnerを出すだけで良いならhooks側でisLoadingフラグを管理するで十分
画面全体にloadingを出したい要件であれば通信状態はdispatch(LOAD)みたいな投げ方をすると良さそう。
複数通信あると通信ごとにuuid発火させるとかはやったことある。いずれにせよ「データと通信状態は独立する」というのが肌感
逆に言えばdataがロード済みでも、それは通信状態の完了・未完了と一致するケースはそれほど多くない印象
normalizrは辛い
確かに構造化してくれるのはうれしいかもしれない
とはいえその分のEntity生成のロジック組み立てコストが高い
また、実際のDBとは違う(構造化される)ので、脳内のコンテキストが高い
ページによって組み立て方がバラけるのも辛い
このページだと親子関係逆が嬉しいとか普通にある
selectorで良い
DBをreduxに入れたいケースはままある。
ただselector系があれば割と十分だったりしない?
code:ts
const SomeItem = ({id}) => {
const value = useSelector( state => state.itemsid ) return <div>{value}</div>
}
const SomeItemByname = ({name}) => {
const value = useSelector( state => state.items.filter(s => s.name === name ) )
return <div>{value}</div>
}
パフォーマンスに問題があったとき使うか?
おそらくNOでは
パフォーマンスに難がある場合の打ち手
サーバー側で解決 BFF
websocket
クライアント側で処理
少なくとも生RESTFulのままやるかというとやらない気がする
クライアント側でやるとして -> Reducerで処理するか?というと自前のキャッシュ処理を組んでhooksから呼び出したくないですか?みたいな。
GraphQLとか
(使ったこと無いのでエアプ)
コンポーネントに近いところ(Containerらへん)でリクエスト処理が投げられるはず
ということで言うとhooksの方が相性よさげにみえる。
リロードなどもより柔軟そう(な印象)
逆にGraphQLの値をReduxに書き戻すってめっちゃしんどそうな印象を持ってる(middlewareが必要?)
もしhooksなどの値とreduxの値を組み合わせたいときは?
hooksでuseMemoなりをuseSelectorと組み合わせれば十分使える