State als Array von Objekten vs Objekt mit der ID

In dem Kapitel überDesigning the State Shape, in den Dokumenten wird empfohlen, Ihren Status in einem Objekt zu belassen, das mit der ID: @ versehen is

Behalten Sie jede Entität in einem Objekt bei, die mit einer ID als Schlüssel gespeichert ist, und verwenden Sie IDs, um auf sie von anderen Entitäten oder Listen zu verweisen.

Sie fahren fort, um @ anzugeb

Denke an den Status der App als Datenbank.

Ich arbeite an der Statusform für eine Liste von Filtern, von denen einige geöffnet sind (sie werden in einem Popup-Fenster angezeigt) oder über ausgewählte Optionen verfügen. Wenn ich "Den Status der App als Datenbank betrachten" las, stellte ich sie mir als JSON-Antwort vor, als würde sie von einer API (die selbst von einer Datenbank unterstützt wird) zurückgegeben.

So dachte ich daran als

[{
    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',
  }]

Die Dokumente schlagen jedoch ein Format vor, das eher @ ähnel

{
   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',
  }
}

n der Theorie sollte es egal sein, solange diedata ist serialisierbar (unter der Überschrift "State").

So ging ich glücklich mit dem Array-of-Objects-Ansatz um, bis ich meinen Reduzierer schrieb.

Mit dem Ansatz "Objektschlüssel nach ID" (und der liberalen Verwendung der Spread-Syntax) wird dasOPEN_FILTER Teil des Reduzierers wird

switch (action.type) {
  case OPEN_FILTER: {
    return { ...state, { ...state[action.id], open: true } }
  }

Wenn der Array-of-Objects-Ansatz verwendet wird, ist er umso ausführlicher (und abhängig von der Hilfsfunktion).

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));
    }
    ...
Also meine Fragen sind dreifach:

1) Ist die Einfachheit des Reduzierers die Motivation, sich für den objektbasierten Ansatz zu entscheiden? Gibt es andere Vorteile für diese Zustandsform?

un

2) Anscheinend erschwert der Ansatz "Objektschlüssel nach ID" den Umgang mit Standard-JSON-Ein- / Ausgängen für eine API. (Deshalb habe ich mich in erster Linie mit dem Array von Objekten befasst.) Wenn Sie sich also für diesen Ansatz entscheiden, verwenden Sie einfach eine Funktion, um sie zwischen dem JSON-Format und dem Statusformformat hin und her zu transformieren? Das scheint klobig. (Wenn Sie diesen Ansatz befürworten, ist ein Teil Ihrer Überlegungen, dass dies weniger klobig ist als die Reduzierung der Anzahl von Objekten oben?)

un

3) Ich weiß, dass Dan Abramov Redux so entworfen hat, dass er theoretisch unabhängig von der Zustandsdatenstruktur ist (wie von @ vorgeschlagen "Konventionell ist der Status der obersten Ebene ein Objekt oder eine andere Schlüsselwertauflistung wie eine Map, abertechnisch kann es jeder Typ sein, " Schwerpunkt meiner). Aber angesichts des oben Gesagten ist es nur "empfehlenswert", ein Objekt mit ID-Schlüssel beizubehalten, oder gibt es andere unvorhergesehene Schwachstellen, auf die ich stoßen werde, wenn ich eine Reihe von Objekten verwende, die es so machen, dass ich das einfach abbrechen sollte Planen und versuchen Sie, sich an ein Objekt zu halten, das mit einer ID versehen ist?

Antworten auf die Frage(6)

Ihre Antwort auf die Frage