我正在做一个游戏。最初,用户在一个地牢中,具有属性:
// state
{
health: 95,
creatures: [ {}, {} ],
bigBoss: {},
lightIsOn: true,
goldReward: 54,
// .. you get the idea
}
现在有许多王国和许多地牢,我们可能想要异步获取这些数据。
在用户状态中表示深层嵌套结构是否更好,在加载时有效缓存所有其他可能的地下城,以及每次我们想要更新属性时(例如action {{1} })我们需要确切地找到我们正在谈论的地牢,或者每次搬到新的地牢时更新顶级属性?
下面的状态显示了嵌套。大多数信息与我的表现对象和动作无关,它们只关心用户当前所在的一个地下城。
TURN_ON_LIGHT
让我回过头来的一件事就是所有干净的缩减器,以前只能执行// state with nesting
{
health: 95,
kingdom: 0,
dungeon: 1,
kingdoms: [
{
dungeons: [
{
creatures: [ {}, {} ],
bigBoss: {},
lightIsOn: true,
goldReward: 54
}
{
creatures: [ {}, {}, {} ],
bigBoss: {},
lightIsOn: false,
goldReward: 79
}
{
//...
}
]
}
{
// ...
}
]
}
之类的操作并更新顶级属性TURN_ON_LIGHT
,允许非常直接的缩减器组合,现在必须进入状态并根据我们当前所在的lightIsOn
和kingdom
更新正确的属性。是否有一种很好的组合减速器的方法保持干净吗?
答案 0 :(得分:2)
在Redux中处理嵌套或关系数据的推荐方法是对其进行规范化,类似于构建数据库的方式。使用具有ID作为键的对象和作为值的项目允许按ID直接查找,使用ID数组来指示排序,以及需要引用项目的状态的任何其他部分应该只存储ID,而不是项目本身。这可以使您的状态更加平坦,并使更新给定项目变得更加直接。
作为其中一部分,您可以在UI中使用多级连接组件。 Redux的一种典型技术是使用连接的父组件来检索多个项的ID,并为每个ID呈现<SomeConnectedChild itemID={itemID} />
。然后,该连接的孩子将使用该ID查找其自己的数据,并将数据传递给其下面的任何表示儿童。从该子树调度的操作将引用该项的ID,并且reducers将能够基于该更新正确的规范化项目条目。
Redux常见问题解答进一步讨论了这个主题:http://redux.js.org/docs/FAQ.html#organizing-state-nested-data。关于Redux在https://github.com/markerikson/react-redux-links/blob/master/react-performance.md#redux-performance的表现的一些文章描述了“传递ID”方法,https://medium.com/@adamrackis/querying-a-redux-store-37db8c7f3b0f也是一个很好的参考。最后,我只是举例说明了归一化状态在https://github.com/reactjs/redux/issues/1824#issuecomment-228609501处看起来的样子。
编辑:
作为后续行动,我最近在Redux文档中添加了一个关于"Structuring Reducers"主题的新部分。特别是,此部分包含有关"Normalizing State Shape"和"Updating Normalized Data"的章节。