W rozdziale dotyczącym projektowania kształtu stanu , dokumenty sugerują, aby zachować stan w obiekcie z kluczem identyfikacyjnym:
Zachowaj każdą jednostkę w obiekcie przechowywanym z identyfikatorem jako kluczem i używaj identyfikatorów do odwoływania się do niej z innych jednostek lub list.
Dalej stwierdzają
Pomyśl o stanie aplikacji jak o bazie danych.
Pracuję nad kształtem stanu dla listy filtrów, z których niektóre będą otwarte (są wyświetlane w wyskakującym okienku) lub będą miały wybrane opcje. Kiedy przeczytałem „Pomyśl o stanie aplikacji jak o bazie danych”, pomyślałem o tym, że myślę o nich jako o odpowiedzi JSON, która byłaby zwracana z interfejsu API (sam w sobie wspierany przez bazę danych).
Więc myślałem o tym jako
[{
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',
}]
Jednak dokumenty sugerują bardziej podobny format
{
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',
}
}
W teorii nie powinno to mieć znaczenia, o ile dane można serializować (pod nagłówkiem „Stan”) .
Więc szczęśliwie poszedłem z podejściem tablicy obiektów, dopóki nie pisałem reduktora.
W przypadku podejścia z kluczem obiektowym według identyfikatora (i liberalnego użycia składni rozproszenia) OPEN_FILTER
część reduktora staje się
switch (action.type) {
case OPEN_FILTER: {
return { ...state, { ...state[action.id], open: true } }
}
Podczas gdy w przypadku podejścia opartego na tablicy obiektów jest to bardziej szczegółowe (i zależne od funkcji pomocniczych)
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));
}
...
Więc moje pytania są trojakie:
1) Czy prostota reduktora jest motywacją do zastosowania podejścia z kluczem obiektowym według identyfikatora? Czy są inne zalety tego stanu?
i
2) Wygląda na to, że podejście z kluczem obiektowym według identyfikatora utrudnia obsługę standardowego wejścia / wyjścia JSON dla interfejsu API. (Dlatego w pierwszej kolejności wybrałem tablicę obiektów). Jeśli więc zastosujesz takie podejście, czy po prostu użyjesz funkcji, aby przekształcić ją tam iz powrotem między formatem JSON a formatem kształtu stanu? To wydaje się niezgrabne. (Chociaż jeśli popierasz takie podejście, czy po części rozumujesz, że jest to mniej niezgrabne niż powyższy reduktor tablicy obiektów?)
i
3) Wiem, że Dan Abramov zaprojektował redukcję, aby teoretycznie być agnostykiem stanu-danych-struktury (jak sugeruje „Zgodnie z konwencją, stan najwyższego poziomu to obiekt lub inna kolekcja klucz-wartość, taka jak mapa, ale technicznie może to być dowolna tekst , wyróżnienie moje). Ale biorąc pod uwagę powyższe, czy jest to tylko "zalecane", aby zachować obiekt z kluczem ID, czy też są inne nieprzewidziane problemy, na które napotkam używając tablicy obiektów, które sprawiają, że powinienem po prostu przerwać planować i próbować trzymać się obiektu z kluczem identyfikacyjnym?