React-Redux复杂(深层)状态对象

Ste*_*yer 30 reactjs immutable.js 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())
}
Run Code Online (Sandbox Code Playgroud)

我需要制作一个减速器来做到这一点:

state.roomList[n].expanded = !state.roomList[n].expanded
Run Code Online (Sandbox Code Playgroud)

我是使用Redux工作流程的新手,解决此问题的最佳方法是使roomList成为一个immutable.js对象,或编写一些代码来深入克隆我的状态对象.

state.roomList还将从未来的功能推送到新的数据.

Summery/Question:在状态深处进行类似更改时,在reducer中返回新状态对象的最佳方法是什么,还是应该更改Redux状态对象的结构?

我做什么最后,Immutable似乎要走了.有一些不可变的技巧可以减少反应渲染时间,并且满足所有项目要求.此外,在项目中尽早使用新库而不进行重大更改.

mar*_*son 51

首先,惯用的Redux鼓励您"规范化"您的状态并尽可能地将其压平.使用按项目ID键入的对象允许直接查找项目,使用ID数组表示排序,以及一个项目需要引用另一个项目的任何地方,它只存储其他项目的ID而不是实际数据.这允许您进行更简单的查找和嵌套对象的更新.请参阅有关嵌套数据的Redux FAQ问题.

此外,您现在看起来正在直接在Redux状态下存储许多函数. 从技术上说,这是有效的,但它肯定不是惯用的,并且会破坏时间旅行调试等功能,所以它非常气馁.Redux FAQ提供了一些关于为什么在Redux状态下存储非可序列化值是个坏主意的更多信息.

编辑:

作为后续工作,我最近在Redux文档中添加了一个关于"构建减速器"主题的新部分.特别是,本节包括"规范化状态形状""更新规范化数据"以及"不可变更新模式"的章节.


xia*_*406 6

减速器组成:将减速器拆分成较小的部件,使减速器小到足以处理简单的数据结构.例如.在你的情况下,你可能有:roomListReducer listItemsReducer listItemReducer.然后在每个减速器上,它将使您更容易阅读您正在处理的状态的哪个部分.它有很大的帮助,因为你的每个reducer都在处理小块数据,你不必担心"我应该深拷贝还是浅拷贝"这样的东西.

不可变的 我个人不使用,immutable.js因为我更喜欢处理普通物体.并且有太多的代码要改变以采用新的API.但这个想法是,确保你的状态变化总是通过纯函数来完成.因此,您可以简单地编写自己的帮助函数来执行您想要的操作,只需确保在处理复杂对象时对它们进行彻底测试.

或者简单地说,你总是可以在每个reducer中深度复制你的状态,然后在副本中变异然后返回副本.但这显然不是最好的方式.

  • @StevenBayer你的州树将保持不变.但是在每个reducer中,您将处理更简单的数据结构.对不起我在帖子里不清楚.此外,您并不总是需要`combineReducer`.Reducers只是将`state`和`action`作为参数的函数.您可以在减速器功能中调用另一个减速器功能,以减少每个减速器的责任. (3认同)
  • combineReducers文档:http://redux.js.org/docs/api/combineReducers.html (2认同)