Redux 嵌套减速器或规范化状态?

Redux nested reducers or normalize state?

我正在用 React 制作一个表单组件,想用 Redux 存储表单和字段状态。

所以我有一个 form reducer 和一个 formField reducer。

我首先跟随直觉,尝试将 formField reducer 嵌套在 form reducer 中。这基本上意味着在 form reducer 和 formField reducer 中都有与 formField 相关的开关案例。

这感觉有点乱(重复代码),所以我在文档中阅读了更多,发现建议将状态归一化。所以我拿走了嵌套的formFields,把它们和forms放在同一层级。

这使 reducer 变得漂亮干净,但现在检索特定表单的 formFields 感觉很糟糕。我基本上每次都遍历所有 formFields,只返回具有正确 "formId" 参数的那些。

Redux 文档指出您应该将状态视为规范化数据库,但他难道没有忘记您没有能够查询结果的奢侈吗?

我错过了什么吗?推荐的解决方法是什么?

据我了解,您的问题与查询派生数据有关。 (即属于表单 X 的字段)。

还有一个名为 reselect 的实用工具,您的用例似乎符合它所解决的问题。

您只需要编写一个需要 formId 的选择器,它将 return 一个表单字段数组。

听起来您将 formFields 状态保存为一个数组,但想将其作为一个对象来查询,其中 formId 是键:

This made the reducer nice and clean, but now retrieving the formFields for a specific form feels horrible. I'm basically looping through all the formFields every time and only returning those with the correct "formId" parameter.

如果把formFields状态改成对象,查询起来会方便很多:formFields[fieldId].

如另一个答案中所述,您可以使用编写可组合的“选择器”来定义如何 compute derived state。那么您的组件代码将很简单,因为准备数据的所有繁重工作都在小型且可组合的选择器中处理。

您可以查看 shopping-cart 示例中的缩减器和选择器,以更好地了解惯用 Redux 应用程序中的状态结构。请注意,此示例对选择器使用普通函数,但我们建议使用 Reselect 以获得更好的性能。