Dans le chapitre sur la conception de la forme de l'état , la documentation suggère de conserver votre état dans un objet indexé par ID:
Conservez chaque entité d'un objet stockée avec un ID comme clé et utilisez des ID pour la référencer à partir d'autres entités ou listes.
Ils continuent à déclarer
Considérez l'état de l'application comme une base de données.
Je travaille sur la forme de l'état pour une liste de filtres, dont certains seront ouverts (ils sont affichés dans une fenêtre contextuelle), ou ont des options sélectionnées. Quand j'ai lu «Pensez à l'état de l'application comme une base de données», j'ai pensé à les considérer comme une réponse JSON car elle serait renvoyée par une API (elle-même soutenue par une base de données).
Alors je pensais à ça comme
[{
id: '1',
name: 'View',
open: false,
options: ['10', '11', '12', '13'],
selectedOption: ['10'],
parent: null,
},
{
id: '10',
name: 'Time & Fees',
open: false,
options: ['20', '21', '22', '23', '24'],
selectedOption: null,
parent: '1',
}]
Cependant, la documentation suggère un format plus semblable à
{
1: {
name: 'View',
open: false,
options: ['10', '11', '12', '13'],
selectedOption: ['10'],
parent: null,
},
10: {
name: 'Time & Fees',
open: false,
options: ['20', '21', '22', '23', '24'],
selectedOption: null,
parent: '1',
}
}
En théorie, cela ne devrait pas avoir d'importance tant que les données sont sérialisables (sous la rubrique «État») .
J'ai donc opté pour l'approche tableau d'objets avec bonheur, jusqu'à ce que j'écrive mon réducteur.
Avec l'approche objet par identifiant (et l'utilisation libérale de la syntaxe de diffusion), la OPEN_FILTER
partie du réducteur devient
switch (action.type) {
case OPEN_FILTER: {
return { ...state, { ...state[action.id], open: true } }
}
Alors qu'avec l'approche tableau d'objets, c'est la plus verbeuse (et dépendante de la fonction d'assistance)
switch (action.type) {
case OPEN_FILTER: {
// relies on getFilterById helper function
const filter = getFilterById(state, action.id);
const index = state.indexOf(filter);
return state
.slice(0, index)
.concat([{ ...filter, open: true }])
.concat(state.slice(index + 1));
}
...
Mes questions sont donc triples:
1) La simplicité du réducteur est-elle la motivation pour aller avec l'approche objet-clé-par-id? Y a-t-il d'autres avantages à cette forme d'État?
et
2) Il semble que l'approche par identifiant d'objet rend plus difficile le traitement des entrées / sorties JSON standard pour une API. (C'est pourquoi j'ai opté pour le tableau d'objets en premier lieu.) Donc, si vous optez pour cette approche, utilisez-vous simplement une fonction pour le transformer d'avant en arrière entre le format JSON et le format de forme d'état? Cela semble maladroit. (Bien que si vous préconisez cette approche, cela fait-il partie de votre raisonnement selon lequel c'est moins maladroit que le réducteur de tableau d'objets ci-dessus?)
et
3) Je sais que Dan Abramov a conçu le redux pour être théoriquement indépendant de la structure des données d'état (comme suggéré par "Par convention, l'état de niveau supérieur est un objet ou une autre collection de valeurs-clés comme une carte, mais techniquement, il peut être n'importe quel type , " je souligne). Mais compte tenu de ce qui précède, est-il simplement "recommandé" de le conserver comme un objet associé à son ID, ou y a-t-il d'autres problèmes imprévus que je vais rencontrer en utilisant un tableau d'objets qui le rendent tel que je devrais simplement abandonner cela planifier et essayer de rester avec un objet saisi par ID?