例えば、以下のようなデータがあるとしましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
const lists = [ { id: '1', user: { username: 'user1', name: 'User 1' }, data: '......', details: [ { id: '1', user: { username: 'user1', name: 'User 2' }, detail: '.....' }, { id: '2', user: { username: 'user2', name: 'User 3' }, detail: '.....' } ] }, ] |
以下のデータが複数回繰り返し出てきているので正規化されていないデータと言えます。
1 |
user: { username: 'user1', name: 'User 2' } |
これだと特定の箇所を更新したいだけなのに他の箇所のコンポーネントも影響してしまいます。
正規化のメリット
- ネストが浅いので複雑性がない。
- 参照の際にfilterせずにダイレクトに参照できる。
- 操作の必要が必要ないデータに対する操作がなくなるためコンポーネントの再描画の観点から便利
正規化されてない状態でのデメリット
- 各エンティティのデータが混在してStoreに保存されているため何処かを更新する際にその対象が適切に更新されているか不明瞭
- データがネストされていてデータの更新ロジックが複雑になったり、想定以上の時間を要する場合がある。
- 不要な再描画を行う可能性が高くなる。
Storeが正規化された状態
データに重複がないこと
重複があると、関係ないコンポーネントまで再レンダリングされる可能性がある。
IDをkeyにアイテム自体がvalueとなる連想配列(オブジェクト)に保持されていること。
ループを回さないで欲しい情報にアクセスができる。forEachやfilterを使わなくて済むのでパフォーマンスが良くなる。
特定のアイテムタイプに対して全てのIDの配列がある場合がある。
具体的にどうするか?
createEntityAdapter
Redux Tool Kitならこれを使うと良いでしょう。
Normalizr
Redux Tool Kitを使用してない場合はこれを使うと良いでしょう。
normalizeする。
1 2 |
const newstate = new schema.Entity("state"); const normalizeState = normalize(state, [newstate]); |
id以外をキーにしたい場合
idAttributeを使います。例えば、以下の例はオブジェクトのキーを「ItemName」というものにしたい場合の例です。
1 2 3 4 5 6 |
const newstate = new schema.Entity( "state", {}, { idAttribute: "ItemName" } ); const normalizeState = normalize(state, [newstate]); |
この記事へのコメントはありません。