У главі Проектування форми стану , документи пропонують зберігати свій стан в об'єкті, введеному за допомогою ідентифікатора:
Зберігайте кожну сутність в об’єкті, що зберігається з ідентифікатором як ключем, і використовуйте ідентифікатори для посилання на неї з інших об’єктів або списків.
Вони продовжують констатувати
Подумайте про стан програми як про базу даних.
Я працюю над формою стану для списку фільтрів, деякі з яких будуть відкритими (вони відображаються у спливаючому вікні) або мають вибрані параметри. Коли я прочитав "Подумайте про стан програми як про базу даних", я подумав про те, щоб сприймати їх як відповідь 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, але технічно це може бути будь-яка тип , " наголос мій). Але з огляду на вищесказане, чи просто "рекомендується" зберігати його як об'єкт, закріплений за допомогою ідентифікатора, чи є інші непередбачені больові точки, на які я зіткнуся, використовуючи масив об'єктів, які роблять це таким, що я повинен просто перервати це планувати і намагатися дотримуватися об’єкта, введеного за допомогою ідентифікатора?