我正在构建一个简单的待办事项应用程序,用户可以在其中创建项目,然后添加待办事项项目。我相信我的状态应该是这样的:
{
projects: {
1: {
id: 1,
title: "New Project",
todos: [1, 2]
}
},
todos: {
1: {
id: 1,
text: "This is the first todo",
isComplete: true,
project: 1
},
2: {
id: 2,
text: "This is the second todo",
isComplete: false,
project: 1
}
}
}
创建新待办事项时,我需要使用新待办事项更新 todos
状态,并且需要更新 projects
状态下的父项目。
处理这个问题的最佳方法是什么?两个 reducer 都需要采取措施来处理这个问题吗?或者是否有某种方式 todos
reducer 可以在 projects
reducer 中调用更新操作?
编辑:以下是我如何更改数据结构以更好地与 redux 配合使用
{
projects: {
condition: {
currentProject: 1
},
entities: {
1: {
id: 1,
title: "New Project"
}
}
},
todos: {
condition: {
currentFilter: 'SHOW_ALL'
},
entities: {
1: {
id: 1,
text: "This is the first todo",
isComplete: true,
project: 1
},
2: {
id: 2,
text: "This is the second todo",
isComplete: false,
project: 1
}
}
}
}
这样,在根级别组合的每个 reducer 都被限定在一个根键的范围内。 实体
会被持久化,但条件
不会。状态的所有其他部分均使用reselect
进行计算。我很想知道其他人如何在仅前端的应用程序中解决类似的问题。
最佳答案
当项目引用其待办事项时,反之亦然,您就在复制数据。除非您正在处理一个非常大的集合,否则我建议不要使用这种模式。相反,每当您需要与项目匹配的待办事项列表时,请过滤待办事项集合。像 reselect
这样的东西非常适合这种情况。
这样当你调度CREATE_TODO
时,你只需要todos
reducer 来监听。
保持 reducer 解耦。
在 reducer 中调度操作是一种反模式。您无法在一个 reducer 中执行某些操作并将该信息直接传递给另一个 reducer 。更好的解决方案是
dispatch({ type: CREATE_TODO, payload: { text: 'dsfdf' }) dispatch({ type: ASSOCIATE_TODO_WITH_PROJECT, payload: { todo: todoid, project: 2 })
但即使这样也行不通,因为你不知道
todoid
是什么。这让我想到...在创建待办事项之前,您不必知道它的 ID。在您的 reducer 设置中,您需要知道待办事项的 id 才能将其添加到项目中。这意味着您需要在操作负载中提供它。但是你的 View 必须生成下一个 id,这并不理想。
在
mapStateToProps
中调用state.todos.filter(todo => todo.project == currentProject.id)
是比弄清楚下一个 id 应该是什么更好的解决方案位于 View 中并通过操作传递它。如果这是通过数据库完成的,那么您可以将类似的内容与
redux-thunk
一起使用export function createTodo(text, project) { return function(dispatch) { dispatch({ type: CREATE_TODO_PENDING }); fetch('/todos', { method: 'POST', body: { text: text, project: project } }) .then(function(response) { // { id: 134452, text: text, project: project } dispatch({ type: CREATE_TODO_SUCCESS, payload: response }) }.catch(err) { dispatch({ type: CREATE_TODO_FAIL }) } } }
如果您使用处理 id 的后端,那么您可以执行上述操作,让两个 reducer 监听事件并同时将待办事项分配给项目,并将项目分配给待办事项。但我仍然不建议这样做。
由于缺乏单一事实来源,您可能会面临数据不同步的风险。如果您的项目 reducer 说一个项目拥有一个
id === 3
的待办事项,但该待办事项却说另一个项目拥有它,那么该待办事项属于谁?显然已经发生了一个错误,但是只要让一个 child 跟踪 parent 就可以完全避免这种情况。不过,如果您使用数据库,那么数据库应该使这些内容保持同步(错误的表面积仍然更大,但可能性较小)。在这种情况下,只要您的客户端数据始终反射(reflect)服务器数据,就应该没问题。
关于reactjs - redux中如何处理父子数据关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33312198/