React-Redux сложные (глубокие) объекты состояния

учитывая мое начальное состояние 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 неизменяемым.объект js или написать код, чтобы сделать глубокий клон моего объекта состояния.

также государство.roomList появятся новые сведения из будущих возможностей.

Летний / Вопрос: каков наилучший способ вернуть новое состояние объект в редукторе при внесении таких изменений глубоко в состояние, или я должен изменить структуру объекта состояния Redux?

что я сделал В конце концов, неизменным кажется путь. Есть несколько трюков с неизменяемым, чтобы уменьшить время рендеринга react, и он отвечает всем требованиям проекта. Также достаточно рано в проекте использовать новую библиотеку без внесения серьезных изменений.

2 ответов


во-первых, idiomatic Redux поощряет вас "нормализовать" свое состояние и сгладить его как можно больше. Используйте объекты с идентификаторами элементов, чтобы разрешить прямой поиск элементов, используйте массивы идентификаторов для обозначения порядка, и везде, где один элемент должен ссылаться на другой, он хранит только идентификатор другого элемента вместо фактических данных. Это позволяет выполнять более простые поиски и обновления вложенных объектов. См.вопрос FAQ Redux о вложенных данных.

кроме того, он выглядит как вы в настоящее время храните ряд функций непосредственно в состоянии Redux. технически это работает, но это определенно не идиоматично и сломает такие функции, как отладка путешествий во времени, поэтому это сильно обескураживает. Redux FAQ дает дополнительную информацию о почему хранение несериализуемых значений в состоянии Redux-плохая идея.

edit:

в качестве продолжения я недавно добавил новый раздел в документы Redux по теме "Структурирование Редукторы". В частности, этот раздел включает главы, посвященные "Нормализация Формы Состояния" и "Обновление Нормализованных Данных", а также "Неизменяемые Шаблоны Обновления".


редуктор составе: Де-составьте ваши редукторы в более небольшие части так, что редуктор будет небольшой достаточно общаться с простой структурой данных. например. В вашем случае вы можете иметь: roomListReducer listItemsReducer listItemReducer. Затем на каждом редукторе вам будет намного легче читать, с какой частью состояния вы имеете дело. Это очень помогает, потому что каждый из ваших редукторов имеет дело с небольшой частью данных, которые вам не нужно беспокоиться о таких вещах, как " должен ли я глубоко копировать или мелкий копия'.

неизменяемые Я лично не использую immutable.js потому что я предпочитаю иметь дело с простыми объектами. и есть слишком много кода для изменения, чтобы принять новый API. Но идея в том, чтобы убедиться, что ваши изменения состояния всегда выполняются через чистые функции. Поэтому вы можете просто написать свои собственные вспомогательные функции, чтобы делать то, что вы хотите, просто убедитесь, что они тщательно протестированы при работе со сложными объектами.

или просто достаточно, вы всегда можете глубоко скопируйте свое состояние в каждом редукторе и мутируйте в копии, а затем верните копию. Но это явно не лучший способ.