В главе, посвященной разработке формы состояния , документы предлагают сохранить ваше состояние в объекте с ключом по идентификатору:
Храните каждую сущность в объекте с идентификатором в качестве ключа и используйте идентификаторы для ссылки на нее из других сущностей или списков.
Они продолжают утверждать
Думайте о состоянии приложения как о базе данных.
Я работаю над формой состояния для списка фильтров, некоторые из которых будут открытыми (они отображаются во всплывающем окне) или с выбранными параметрами. Когда я прочитал «Думайте о состоянии приложения как о базе данных», я подумал о том, чтобы думать о них как о ответе JSON, поскольку он будет возвращен из API (сам поддерживается базой данных).
Так что я думал об этом как
[{
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',
}]
Однако в документах предлагается формат, больше похожий на
{
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',
}
}
Теоретически это не имеет значения, если данные можно сериализовать (под заголовком «Состояние») .
Так что я с радостью использовал подход с использованием массива объектов, пока не написал свой редуктор.
При подходе объектного ключа по идентификатору (и либерального использования синтаксиса распространения) OPEN_FILTER
часть редуктора становится
switch (action.type) {
case OPEN_FILTER: {
return { ...state, { ...state[action.id], open: true } }
}
Принимая во внимание, что подход с использованием массива объектов, он более подробный (и зависит от вспомогательных функций)
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));
}
...
Итак, у меня три вопроса:
1) Является ли простота редуктора мотивацией для перехода к подходу с ключом объекта по идентификатору? Есть ли у этой государственной формы другие преимущества?
а также
2) Похоже, что подход с использованием объектного ключа по идентификатору усложняет работу со стандартным вводом / выводом JSON для API. (Вот почему я в первую очередь выбрал массив объектов.) Итак, если вы придерживаетесь этого подхода, вы просто используете функцию для преобразования его между форматом JSON и форматом формы состояния? Это кажется неуклюжим. (Хотя, если вы отстаиваете этот подход, вы считаете, что это менее неуклюже, чем редуктор массива объектов выше?)
а также
3) Я знаю, что Дэн Абрамов разработал redux так, чтобы теоретически не зависеть от структуры данных состояния (как предполагает «По соглашению, состояние верхнего уровня - это объект или некоторая другая коллекция значений ключа, например Map, но технически это может быть любое типа " курсив мой). Но, учитывая вышеизложенное, просто «рекомендуется» сохранить его как объект с ключом по идентификатору, или есть другие непредвиденные болевые точки, с которыми я собираюсь столкнуться, используя массив объектов, которые делают его таким, что я должен просто прервать это планировать и пытаться придерживаться объекта с ключом по ID?