2017-06-06 5 views
1

J'ai une réponse API qui a beaucoup d'entités imbriquées. J'utilise normalizr pour maintenir l'état de redux aussi plat que possible.
Par exemple. la réponse api ressemble ci-dessous:
Redux + Normalizr: Ajouter et supprimer des entités normalisées dans l'état Redux

{ 
    "id": 1, 
    "docs": [ 
    { 
     "id": 1, 
     "name": "IMG_0289.JPG" 
    }, 
    { 
     "id": 2, 
     "name": "IMG_0223.JPG" 
    } 
    ], 
    "tags": [ 
    { 
     "id": "1", 
     "name": "tag1" 
    }, 
    { 
     "id": "2", 
     "name": "tag2" 
    } 
    ] 
} 

Cette réponse est normalisée à l'aide normalizr en utilisant le schéma ci-dessous:

const OpeningSchema = new schema.Entity('openings', { 
    tags: [new schema.Entity('tags')], 
    docs: [new schema.Entity('docs')] 
}); 

et ci-dessous est à quoi il ressemble alors:

{ 
    result: "1", 
    entities: { 
    "openings": { 
     "1": { 
      "id": 1, 
      "docs": [1,2], 
      "tags": [1,2] 
     } 
    }, 
    "docs": { 
     "1": { 
     id: "1", 
     "name": "IMG_0289.JPG" 
     }, 
     "2": { 
     id: "2", 
     "name": "IMG_0223.JPG" 
     } 
    }, 
    "tags": { 
     "1": { 
      "id": 1, 
      "name": "tag1" 
     }, 
     "2": { 
      "id": 2, 
      "name": "tag2" 
     } 
    } 
    } 
} 

L'état de redux ressemble maintenant à quelque chose comme ci-dessous:

state = { 
    "opening" : { 
     id: 1, 
     tags: [1,2], 
     docs: [1,2] 
    }, 
    "tags": [ 
     { 
      "id":1, 
      "name": "tag1" 
     }, 
     { 
      "id":2, 
      "name": "tag2" 
     } 
    ], 
    "docs": [ 
     { 
      "id":1, 
      "name": "IMG_0289.JPG" 
     }, 
     { 
      "id":2, 
      "name": "IMG_0223.JPG" 
     } 
    ] 
} 

Maintenant, si j'envoie une action pour ajouter un tag, il ajoute un objet tag-state.tags mais il ne met pas à jour tableau state.opening.tags. Même comportement lors de la suppression d'une balise. Je conserve opening, tags et docs dans trois réducteurs différents.

Ceci est une incohérence dans l'état. Je peux penser à des façons suivantes pour maintenir l'état cohérent:

  1. J'envoie une action à mettre à jour les balises et l'écouter à la fois réducteur et tagsopening réducteur et les balises de mise à jour par la suite aux deux endroits.
  2. La demande de correctif pour mettre à jour l'ouverture avec des étiquettes renvoie la réponse d'ouverture. Je peux à nouveau envoyer l'action qui normalise la réponse et définir les balises, l'ouverture etc. avec une cohérence appropriée.

Quelle est la bonne façon de faire cela. Les entités ne devraient-elles pas observer les changements apportés aux entités liées et effectuer les changements eux-mêmes? Ou il existe d'autres modèles qui pourraient être suivis une telle action.

Répondre

2

Premier à résumer comment normalizr fonctionne: normalizr aplatit réponse API imbriquée aux entités définies par vos schémas. Ainsi, lorsque vous avez effectué votre demande initiale d'API GET openings, normalizr a aplati la réponse et créé votre Redux entities et les objets aplatis: openings, docs, tags. Vos suggestions sont viables, mais je trouve que l'avantage réel de normalizr est de séparer les données de l'API de l'état de l'interface utilisateur; donc je ne mets pas à jour les données dans le magasin Redux moi-même ... Toutes mes données API sont conservées dans entities et ils ne sont pas modifiés par moi; ce sont des données back-end à la vanille ... Tout ce que je fais est de faire un GET lors d'un changement d'état des opérations API, et de normaliser la réponse GET. Il y a une petite exception pour le cas DELETE que je développerai plus tard ... Un middleware traitera de tels cas, donc vous devriez en utiliser un si vous n'avez pas utilisé. J'ai créé mon propre middleware, mais je sais que redux-promise-middleware est très populaire.

Dans votre jeu de données ci-dessus; Lorsque vous ajoutez un nouveau tag, je suppose que vous créez une API POST pour ce faire, ce qui met à jour le back-end.Ensuite, vous devriez faire un autre GET openings qui mettra à jour le entities pour les ouvertures et tous ses schémas imbriqués.

Lorsque vous supprimez un tag, par ex. tag [2], lors de l'envoi de la requête DELETE au back-end, vous devez annuler l'objet supprimé dans votre état d'entités, c'est à dire. entities.tags[2] = null avant de faire le GET openings à nouveau pour mettre à jour vos entités normalizr.