Комплексные (глубокие) объекты состояния React-Redux
Учитывая мое начальное состояние редукции:
const state = {
currentView: 'ROOMS_VIEW',
navbarLinks: List([
{name: 'Rooms', key: 'ROOMS_VIEW'},
{name: 'Dev', key: ''}
]),
roomListsSelected: {group: 0, item: 0},
roomLists: [
{
name: "Filters",
expanded: true,
listItems: [
{ icon: 'images/icon-warning.svg', name: 'Alerts', filter: room => room.hasAlert },
{ icon: 'images/icon-playlist.svg', name: 'In Progress', filter: room => room.progress > 20 },
{ icon: 'images/icon-playlist.svg', name: 'Almost Done', filter: room => room.progress > 90 },
{ icon: 'images/icon-playlist.svg', name: 'Complete', filter: room => room.status === 'complete' },
{ icon: 'images/icon-playlist.svg', name: 'Recently Completed', filter: room => false },
{ icon: 'images/icon-playlist.svg', name: 'All Rooms', filter: room => true }
]
}
],
rooms: List(generateRooms())
}
Мне нужно сделать редуктор, который делает это:
state.roomList[n].expanded = !state.roomList[n].expanded
Я новичок в использовании рабочего процесса Redux, и лучший способ решить это - сделать roomList объектом immutable.js или написать некоторый код, чтобы сделать глубокий клон моего объекта состояния.
Также state.roomList будет получать новые данные от будущих функций.
Summery/Question:. Каков наилучший способ вернуть новый объект состояния в редуктор при внесении таких изменений, как это глубоко в состояние, или мне нужно изменить структуру объекта состояния Redux?
Что я сделал. В конце концов, Неизменяемый, кажется, путь. Есть несколько трюков с неизменяемым, чтобы уменьшить время рендеринга, и он отвечает всем требованиям проекта. Также в проекте достаточно рано использовать новую библиотеку без существенных изменений.
Ответы
Ответ 1
Во-первых, идиоматический Redux призывает вас "нормализовать" ваше состояние и максимально сгладить его. Используйте объекты, введенные с помощью идентификаторов элементов, чтобы разрешить прямой поиск элементов, использовать массивы идентификаторов для обозначения упорядочения, и в любом месте, где один элемент должен ссылаться на другой, он сохраняет только идентификатор другого элемента вместо фактических данных. Это позволяет вам упростить поиск и обновление вложенных объектов. См. Вопрос о часто задаваемых вопросах Redux для вложенных данных: http://redux.js.org/docs/faq/OrganizingState.html#organizing-state-nested-data.
Кроме того, похоже, что вы в настоящее время сохраняете несколько функций непосредственно в вашем состоянии Redux. Технически это работает, но это определенно не идиоматично, и будет ломать такие функции, как отладка во времени, поэтому она сильно обескуражена. В FAQ Redux вы найдете дополнительную информацию о том, почему это вообще не очень хорошая идея: http://redux.js.org/docs/faq/OrganizingState.html#organizing-state-non-serializable.
изменить:
В качестве продолжения я недавно добавил новый раздел в документы Redux, на тему "Структурирование редукторов" . В частности, этот раздел включает главы на "Нормализация формы государства" и "Обновление Нормализованные данные" , а также "Неизменяемые шаблоны обновлений" .
Ответ 2
Состав редуктора:
Декомпозицию ваших редукторов на меньшие части, чтобы редуктор был достаточно мал, чтобы справляться с простой структурой данных. например. В вашем случае вы можете: roomListReducer
listItemsReducer
listItemReducer
. Затем на каждом редукторе его гораздо проще будет прочитать, в какой части государства вы имеете дело. Это очень помогает, потому что каждый из ваших редукторов имеет дело с небольшим количеством данных, которые вам не нужно беспокоиться, например: "Должен ли я делать глубокую копию или мелкую копию".
Неизменное
Я лично не использую immutable.js
, потому что предпочитаю иметь дело с обычными объектами. и есть слишком много кода для изменения, чтобы принять новый API. Но идея в том, что ваши изменения состояния всегда выполняются с помощью чистых функций. Поэтому вы можете просто написать свои собственные вспомогательные функции, чтобы делать то, что вы хотите, просто убедитесь, что они тщательно протестированы при работе со сложными объектами.
Или просто достаточно, вы всегда можете копировать свое состояние в каждом редукторе и мутировать в копии, а затем возвращать копию. Но это, очевидно, не самый лучший способ.