Nel capitolo sulla progettazione della forma dello stato , i documenti suggeriscono di mantenere il proprio stato in un oggetto con chiave ID:
Mantieni ogni entità in un oggetto archiviata con un ID come chiave e usa gli ID per fare riferimento ad essa da altre entità o elenchi.
Continuano a dichiarare
Pensa allo stato dell'app come a un database.
Sto lavorando alla forma dello stato per un elenco di filtri, alcuni dei quali saranno aperti (vengono visualizzati in un popup) o avranno opzioni selezionate. Quando ho letto "Pensa allo stato dell'app come a un database", ho pensato di considerarli come una risposta JSON in quanto sarebbe stata restituita da un'API (a sua volta supportata da un database).
Quindi ci stavo pensando come
[{
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',
}]
Tuttavia, i documenti suggeriscono un formato più simile
{
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',
}
}
In teoria, non dovrebbe avere importanza fintanto che i dati sono serializzabili (sotto il titolo "Stato") .
Quindi sono andato con l'approccio della matrice di oggetti felicemente, fino a quando non stavo scrivendo il mio riduttore.
Con l'approccio object-keyed-by-id (e l'uso liberale della sintassi diffusa), la OPEN_FILTER
parte del riduttore diventa
switch (action.type) {
case OPEN_FILTER: {
return { ...state, { ...state[action.id], open: true } }
}
Considerando che con l'approccio array di oggetti, è il più dettagliato (e dipendente dalla funzione di supporto)
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));
}
...
Quindi le mie domande sono triplici:
1) La semplicità del riduttore è la motivazione per seguire l'approccio object-keyed-by-id? Ci sono altri vantaggi in quella forma di stato?
e
2) Sembra che l'approccio object-keyed-by-id renda più difficile gestire l'ingresso / uscita JSON standard per un'API. (Ecco perché ho scelto l'array di oggetti in primo luogo.) Quindi, se segui questo approccio, usi solo una funzione per trasformarlo avanti e indietro tra il formato JSON e il formato della forma dello stato? Sembra goffo. (Anche se sostenete questo approccio, fa parte del vostro ragionamento che è meno goffo del riduttore di array di oggetti sopra?)
e
3) So che Dan Abramov ha progettato il redux per essere teoricamente indipendente dalla struttura dei dati di stato (come suggerito da "Per convenzione, lo stato di primo livello è un oggetto o qualche altra raccolta di valori-chiave come una mappa, ma tecnicamente può essere qualsiasi tipo ", enfasi mia). Ma dato quanto sopra, è semplicemente "consigliato" mantenerlo un oggetto codificato da ID, o ci sono altri punti deboli imprevisti in cui mi imbatterò usando una serie di oggetti che lo rendono tale che dovrei semplicemente interromperlo pianificare e provare a restare con un oggetto con chiave ID?