No capítulo sobre como projetar a forma do estado , os documentos sugerem manter seu estado em um objeto codificado por ID:
Mantenha cada entidade em um objeto armazenado com um ID como uma chave e use IDs para referenciá-lo a partir de outras entidades ou listas.
Eles continuam a afirmar
Pense no estado do aplicativo como um banco de dados.
Estou trabalhando na forma de estado para uma lista de filtros, alguns dos quais serão abertos (são exibidos em um pop-up) ou têm opções selecionadas. Quando li "Pense no estado do aplicativo como um banco de dados", pensei em pensar neles como uma resposta JSON, pois seria retornada de uma API (ela própria apoiada por um banco de dados).
Então eu estava pensando nisso como
[{
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',
}]
No entanto, os documentos sugerem um formato mais parecido com
{
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',
}
}
Em teoria, isso não deve importar, desde que os dados sejam serializáveis (sob o título "Estado") .
Então, fui feliz com a abordagem de matriz de objetos, até que estava escrevendo meu redutor.
Com a abordagem object-keyed-by-id (e uso liberal da sintaxe de propagação), a OPEN_FILTER
parte do redutor torna-se
switch (action.type) {
case OPEN_FILTER: {
return { ...state, { ...state[action.id], open: true } }
}
Considerando que, com a abordagem de matriz de objetos, é mais prolixo (e dependente da função auxiliar)
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));
}
...
Portanto, minhas perguntas são três:
1) A simplicidade do redutor é a motivação para seguir a abordagem de objeto-chave-por-id? Existem outras vantagens nessa forma de estado?
e
2) Parece que a abordagem objeto-chave-por-id torna mais difícil lidar com entrada / saída JSON padrão para uma API. (É por isso que optei pela matriz de objetos em primeiro lugar.) Então, se você seguir essa abordagem, você apenas usa uma função para transformá-la entre o formato JSON e o formato de estado? Isso parece desajeitado. (Embora, se você defender essa abordagem, parte do seu raciocínio seja menos desajeitado do que o redutor de matriz de objetos acima?)
e
3) Eu sei que Dan Abramov projetou redux para ser teoricamente agnóstico de estrutura de dados de estado (como sugerido por "Por convenção, o estado de nível superior é um objeto ou alguma outra coleção de valor-chave como um Mapa, mas tecnicamente pode ser qualquer tipo , " ênfase minha). Mas, dado o exposto acima, é apenas "recomendado" mantê-lo como um objeto codificado por ID, ou há outros pontos de dor imprevistos que vou encontrar usando uma matriz de objetos que o tornam tal que eu deveria simplesmente abortar isso planeja e tenta ficar com um objeto codificado por ID?
sort_by
? const sorted = _.sortBy(collection, 'attribute');