jsonの正規化
正規化の為のアプローチ
データの各ネストはstateのtableにする
code:json
{
"post1": { ... }, // ←これが1テーブル。中にユニークなidを持つ
"post2": { ... },
...
}
1つのテーブルの中にはidがある
上の例ではpostId的な
idの配列を持つプロパティを用意する
code:json
{
posts: {
byId: { ... }, // この中に上のような具体的なデータ
}
}
つまりほぼすべてのデータは以下のようなinterfaceになるのか
code:ts
type Data<T> = {
byId: T;
allIds: string[]; // number[]でも
}
どのへんが嬉しいか
変更が必要なときにデータの中の一箇所を変更するだけで済む
当たり前っぽく聞こえるが正規化を上手くしていないとデータの中の複数箇所を変更する処理が必要になったりする
もちろん忘れる子もあるだろう、それがバグの原因になる
とは言っても、削除したりする場合はbyIdとallIdの二箇所を変更しないといけないな?mrsekut.icon
ネストが浅くなる
このページの正規化前と正規化後の例を見るとぜんぜん違うのがわかるな 正規化後では、postに対するコメントはcommentIdしか見ていない
コメントの内容自体は別の場所に保存しているんやな
reducerの分離がしやすくなる
テーブルとIdさえわかれば、データを特定できる
データはそれぞれ独立しているから、View側で無駄なrenderが走らない
例えば、comment1が更新された時に、comment2は更新しないので、無駄にrenderされない
悪い点
View側では正規化したデータは扱いにくい
commentsIdからコメントの内容を取ってこないといけない
なので毎回denormalizeすることになる(?)
参考
ある箇所で部分的なfetchをした場合に、順序に依ってViewが崩れる
例えば、マイページと、タイムラインを考える
タイムラインでは、ユーザー情報の一部鹿必要としない。
例えば、ニックネームや自己紹介の上は必要としない
一方で、マイページでは必要とする
タイムラインもマイページの情報も同じmapにツッコんでいると、
タイムラインが後で取得された場合に、マイページを見ると、自己紹介などが表示されない
解決策
部分的なfetchをしない
情報の多いものを採用して更新する
「情報の多いもの」で判断するので「新しいもの」と判断できない
冪等性がない
非同期で複数のactionを発行したときに、同じmapを更新すると、順序によって結果が変わる
これは別に正規化関係ないかmrsekut.icon
同じstateを更新するactionを別々に非同期で更新すると順序に依存する
stateの一つ一つが大きすぎるんだよな
各userBaseごとにreducerをつくるとかしないといけない?
ノートの集約と、分類をし直そう
類似ページ
まず、Redux依存するものと、そうでないものにわけたい
単にModel定義だけであれば、Reduxは関係ない
その時点でも正規化が必要なのか自体もまだ良くわかっていない
読んだけど、よく理解できていないのでもう一度読もう
参考