React-Redux 复杂(深)状态对象
React-Redux complex (deep) state objects
鉴于我的初始 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 将从未来的功能中向其推送新数据。
总结/问题:当在状态深处进行这样的更改时,在 reducer 中 return 新状态对象的最佳方法是什么,或者我应该更改 Redux 状态对象的结构?
我做了什么 最后,不可变似乎是可行的方法。 Immutable 有一些技巧可以减少反应渲染时间,它满足所有项目要求。此外,在项目中使用新库而不进行重大更改还为时过早。
减速机组成:
将你的 reducer 分解成更小的部分,这样 reducer 就足够小以处理简单的数据结构。例如。在您的情况下,您可能有:roomListReducer
listItemsReducer
listItemReducer
。然后在每个 reducer 处,它会让你更容易阅读你正在处理的状态的哪一部分。它有很大帮助,因为你的每个减速器都在处理小块数据,你不必担心像 'should i deep copy or shallow copy'.
这样的事情
不可变
我个人不使用 immutable.js
因为我更喜欢处理普通对象。并且有太多的代码需要更改以采用新的 API。但想法是,确保您的状态更改始终通过纯函数完成。因此,你可以简单地编写自己的辅助函数来做你想做的事,只要确保在处理复杂对象时对它们进行了彻底的测试。
或者足够简单,您始终可以在每个减速器中深度复制您的状态,然后在副本中进行变异,然后 return 副本。但这显然不是最好的方式。
首先,惯用的 Redux 鼓励您 "normalize" 您的状态并尽可能地扁平化。使用以项目 ID 为键的对象以允许直接查找项目,使用 ID 数组表示排序,以及一个项目需要引用另一个项目的任何地方,它只存储另一个项目的 ID 而不是实际数据。这使您可以更简单地查找和更新嵌套对象。参见 the Redux FAQ question on nested data。
此外,您目前似乎正在将许多函数直接存储在 Redux 状态中。 技术上 可行,但它绝对不是惯用的,并且会破坏时间旅行调试等功能,因此强烈建议不要使用。 Redux FAQ 提供了更多关于 why storing non-serializable values in your Redux state is a bad idea.
的信息
编辑:
作为后续行动,我最近在 Redux 文档中添加了一个新部分,主题是 "Structuring Reducers". In particular, this section includes chapters on "Normalizing State Shape" and "Updating Normalized Data", as well as "Immutable Update Patterns"。
鉴于我的初始 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 将从未来的功能中向其推送新数据。
总结/问题:当在状态深处进行这样的更改时,在 reducer 中 return 新状态对象的最佳方法是什么,或者我应该更改 Redux 状态对象的结构?
我做了什么 最后,不可变似乎是可行的方法。 Immutable 有一些技巧可以减少反应渲染时间,它满足所有项目要求。此外,在项目中使用新库而不进行重大更改还为时过早。
减速机组成:
将你的 reducer 分解成更小的部分,这样 reducer 就足够小以处理简单的数据结构。例如。在您的情况下,您可能有:roomListReducer
listItemsReducer
listItemReducer
。然后在每个 reducer 处,它会让你更容易阅读你正在处理的状态的哪一部分。它有很大帮助,因为你的每个减速器都在处理小块数据,你不必担心像 'should i deep copy or shallow copy'.
不可变
我个人不使用 immutable.js
因为我更喜欢处理普通对象。并且有太多的代码需要更改以采用新的 API。但想法是,确保您的状态更改始终通过纯函数完成。因此,你可以简单地编写自己的辅助函数来做你想做的事,只要确保在处理复杂对象时对它们进行了彻底的测试。
或者足够简单,您始终可以在每个减速器中深度复制您的状态,然后在副本中进行变异,然后 return 副本。但这显然不是最好的方式。
首先,惯用的 Redux 鼓励您 "normalize" 您的状态并尽可能地扁平化。使用以项目 ID 为键的对象以允许直接查找项目,使用 ID 数组表示排序,以及一个项目需要引用另一个项目的任何地方,它只存储另一个项目的 ID 而不是实际数据。这使您可以更简单地查找和更新嵌套对象。参见 the Redux FAQ question on nested data。
此外,您目前似乎正在将许多函数直接存储在 Redux 状态中。 技术上 可行,但它绝对不是惯用的,并且会破坏时间旅行调试等功能,因此强烈建议不要使用。 Redux FAQ 提供了更多关于 why storing non-serializable values in your Redux state is a bad idea.
的信息编辑:
作为后续行动,我最近在 Redux 文档中添加了一个新部分,主题是 "Structuring Reducers". In particular, this section includes chapters on "Normalizing State Shape" and "Updating Normalized Data", as well as "Immutable Update Patterns"。