【发布时间】: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