【问题标题】:Strategy for data management in ReactReact 中的数据管理策略
【发布时间】:2016-10-26 04:40:05
【问题描述】:

上下文/背景

在现在的一些项目中,我似乎面临着一个共同的问题,但我仍然觉得我没有找到解决它的可靠方法。

我正在使用 React、Redux 和 React Router。

当前状态

最简单的是,我有一个页面,其中包含一系列可保存的表单,所有这些表单都可以在查看模式和编辑模式下存在:

+--------------------------+
| EDIT MODE                |
+--------------------------+
|                          |
|  <input name="A"/>       |
|  <input name="B"/>       |
|                          |
|  <button label="save"/>  |
+--------------------------+
|                          |
|  <input name="C"/>       |
|  <input name="D"/>       |
|                          |
|  <button label="save"/>  | 
+--------------------------+

+--------------------------+
| VIEW MODE         [edit] |
+--------------------------+
|  readonly A              |
|  readonly B              |
|                          |
|  readonly A              |
|  readonly B              |
+--------------------------+

所有表单都封装在一个 Request 组件中,该组件接受一个端点 prop,并在挂载时获取数据。请求完成后,它将呈现其子项。

示例页面:网址:owner/1/pets

const ownerId = props.params.id;

<Request endpoint={`api/owner/{ownerId}/pets`}>
    <OwnerDetails id={ownerId} />     
    <Pets ownerId={ownerId} />
  }}
</Request>

请求成功后的reducer(注意已经规范化):

{
    "tables": {
        "pets": {
            "1": { "id":"1", "name":"max", "owner": 1 },
            "2": { "id":"2", "name":"yella", "owner": 1 }
        },
        "owner": {
            "1": { "id":"1", "name": "jim" }
        }
    }
}

那么每个Form都是一个连接的组件,并且根据一个简单传入的id知道它需要的状态切片。

每个表单还有一个 onChange 动作,它被传递到每个表单输入。 onChange 更新状态的“草稿”切片。

所以当用户在宠物 1 的编辑模式下输入以下输入时:

完整状态如下:

{
    "tables": {
        "pets": {
            "1": { "id":"1", "name":"max", "owner": 1 },
            "2": { "id":"2", "name":"yella", "owner": 1 }
        },
        "owner": {
            "1": { "id":"1", "name": "jim" }
        }
    },
    "draft": {
        "pets": {
            "1": { "name": "new name" },
        }
    }
}

动作/减速器

onChange => # updates the draft slice of state
save =>     # sends all data in draft to the server to be saved, upon being saved, the draft slice for that particular form is emptied, and table slice is updated with new data - in other words, the table slice is always the latest reflection of the server. 

在编辑模式下,连接的表单将抓取表格状态并将其与草稿状态合并,以“全面了解”。因此,如果我们处于上面的当前 reducer 状态,并查看 pet 1,连接的表单将获取所有 tables.pets.1 数据,然后合并顶部的 draft.pets.1 数据。在视图模式下,它只需要抓取表格数据(在视图模式下会忽略草稿数据)。

问题

这感觉有点煮过头了。提取和合并草稿和表格数据感觉很尴尬,即使使用选择器也是如此。当表单可以具有嵌套元素时,从存储状态切片更新和提取数据的问题会更加严重。

问题

处理草稿和状态中可能存在的复杂、多种形式的更具体的策略是什么?

【问题讨论】:

    标签: javascript forms reactjs redux


    【解决方案1】:

    总体而言,这似乎是一种相当可靠的方法。它实际上与我在自己的应用程序中所做的非常接近,尽管我不必“合并”数据本身——当我开始编辑时,与正在编辑的项目相关的所有数据都会被复制到“草稿”切片中.

    但是是的,这种方法对我来说看起来不错。

    编辑

    更新:作为a series on "Practical Redux" 的前两部分,我在 Redux-ORM 上发表了几篇文章,讨论了我从自己使用 Redux 的经验中开发的技术。我计划在以后的帖子中讨论“草稿编辑”的概念。

    第二次更新:我刚刚发布了Practical Redux Part 8: Form Draft Data Management,它展示了如何实现此处描述的方法。

    【讨论】:

    • 感谢@markerikson(感谢您在 reddit 输入和超赞列表中对 react 社区的出色贡献)。我曾讨论过在点击编辑时复制到草稿 - 它可能会简化一些事情。
    • 只是想在上面的评论中添加一些内容-似乎 redux orm 可能有助于简化前端的数据结构,尤其是在映射到后端时
    • 是的,我可能是 Redux-ORM 最重要的推动者(甚至超过了它的作者 @tommikaikkonen !)。我在我的应用程序中大量使用它。事实上,我希望写一系列博客文章来描述我在我的应用程序中提出的东西,而“使用 Redux-ORM”和“管理草稿数据”是我想要涵盖的两个主题。几周前,我在reddit.com/r/reactjs/comments/56lzxg/… 列出了我计划的主题。目前正在尝试找出一些似是而非的场景作为帖子的背景。
    • 太棒了!我会留意的!我会在 /r/reactjs 上查看文章何时发布。谢谢
    • 嘿。我实际上还没有在那里提交任何帖子,但我想我可以。我已经在推特上发布了一个链接。如果您想订阅博客本身,请在 blog.isquaredsoftware.com 。我真的很想在这个周末的后期准备方面取得一些进展,但我们会看看进展如何。最大的问题是我想给出一些好的例子和用例,而不仅仅是抛出一些复制粘贴的代码和一些解释。
    【解决方案2】:

    我建议您使用标准化结构。 1)您将减少内存使用量。 2)更新会很容易。 Redux Storage Strategy

    为此,我相信https://github.com/paularmstrong/normalizr 会非常棒。

    【讨论】: