Состояние как массив объектов против объекта с ключом по идентификатору
В главе оРазработка Государственной Формы, документы предлагают сохранить ваше состояние в объекте с ключом ID:
Сохраняйте каждый объект в объекте, хранящемся с идентификатором в качестве ключа, и используйте идентификаторы для ссылки на него из других объектов или списков.
Они продолжают заявлять
Думайте о состоянии приложения как о базе данных.
Я работаю над формой состояния для списка фильтров, некоторые из которых будут открыты (они отображаются во всплывающем окне) или имеют выбранные параметры. Когда я прочитал «Подумайте о состоянии приложения как о базе данных», я подумал о том, чтобы воспринимать их как ответ 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) Я знаю, что Дэн Абрамов разработал редукс, чтобы теоретически быть независимым от структуры данных (как это было предложено«По соглашению, состояние верхнего уровня - это объект или какой-либо другой набор значений ключа, такой как Map, нотехнически это может быть любой тип,» акцент мой). Но, учитывая вышесказанное, это просто «рекомендуется» сохранить объект с ключом ID или есть другие непредвиденные болевые точки, с которыми я столкнусь, используя массив объектов, которые делают его таким, что я должен просто прекратить это планировать и пытаться придерживаться объекта с ключом по идентификатору?