React

时间:2016-10-26 04:40:06

标签: javascript forms reactjs redux

上下文/背景

现在在一些项目中,我似乎面临着一个共同的问题,我仍然不觉得自己已经创造了一个可靠的解决方法。

我正在使用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,而mount将获取数据。一旦请求完成,它将呈现其子女。

示例页面:网址: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更新&#34;草案&#34;一片状态。

因此,当用户在宠物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. 

已连接的表单将抓取并将表状态与草稿状态合并到&#34;获取完整的图片&#34;在编辑模式下。因此,如果我们处于上面的当前reducer状态,并查看pet 1,则连接的表单将获取所有tables.pets.1数据,然后合并顶部draft.pets.1数据。在视图模式下,它只需要获取表数据(在视图模式下忽略草稿数据)。

问题

这感觉有些过度烹饪。即使使用选择器,提取和合并草稿和表格数据也感觉很尴尬。当表单可以具有嵌套元素时,更新和从商店片状态中提取数据的问题会加剧。

问题

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

2 个答案:

答案 0 :(得分:1)

这似乎是一个相当坚实的方法。它实际上非常接近我在自己的应用程序中所做的事情,尽管我没有必要&#34;合并&#34;数据本身 - 与正在编辑的项目相关的所有数据都被复制到&#34;草稿&#34;我开始编辑时切片。

但是,这种方法对我来说很好。

修改

更新:我已经在Redux-ORM上发布了几篇帖子作为a series on "Practical Redux"的前两部分,讨论了我根据自己的Redux经验开发的技术。我打算讨论&#34;草案编辑&#34;概念在后面的文章中。

第二次更新:我刚刚发布了Practical Redux Part 8: Form Draft Data Management,其中显示了如何实施此处所述的方法。

答案 1 :(得分:0)

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

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