我正在构建一个简单的待办事项应用,用户可以在其中创建项目,然后添加待办事项。我相信我的州应该是这样的:
{
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
状态的父项目。
处理此问题的最佳方法是什么?两个减速器都需要采取措施来解决这个问题吗?或者,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都被限定为一个根密钥。 entities
是持久的,condition
不是。状态的所有其他部分都使用reselect
计算。我很想知道其他人是如何在前端应用程序中解决类似问题的。
答案 0 :(得分:5)
当项目引用其待办事项时,反之亦然,您将重复数据。除非您正在处理一个非常大的集合,否则我建议不要使用该模式。相反,只要您需要与项目匹配的待办事项列表,请过滤todos集合。像reselect
这样的东西是理想的。
这样,当您发送CREATE_TODO
时,您只需要todos
缩减器来收听。
让您的Reducer脱钩。
reducers中的调度操作是一种反模式。您无法在一个reducer中执行某些操作,并将该信息直接传递给另一个。更好的解决方案是
dispatch({ type: CREATE_TODO, payload: { text: 'dsfdf' })
dispatch({ type: ASSOCIATE_TODO_WITH_PROJECT, payload: { todo: todoid, project: 2 })
但即使这样做也不会有效,因为你不知道todoid
是什么。这让我想起......
在创建待办事项之前,您不必知道待办事项的ID。在您的reducer设置中,您需要知道待办事项的ID才能将其添加到项目中。这意味着您需要在动作有效负载中提供它。但是,你的观点必须生成下一个id,这是不理想的。
在state.todos.filter(todo => todo.project == currentProject.id)
中调用mapStateToProps
比解决视图中下一个ID应该是什么以及通过操作传递它更好。
如果使用db完成此操作,那么您将使用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的后端,那么您可以执行上述操作并让两个reducers侦听事件并同时将todos分配给项目和项目。但我仍然不建议这样做。
由于缺乏单一的事实来源,您可能会因数据不同步而面临风险。如果你的项目减速器说一个项目拥有一个id === 3
的todo,但是todo说一个不同的项目拥有它,那个todo属于哪个?显然已经发生了一个错误,但只有让一个孩子跟踪父母,就可以完全避免这个错误。
尽管如此,如果您正在使用数据库,那么数据库应该保持这些事情同步(更多的表面区域用于错误,但不太可能)。在这种情况下,只要您的客户数据始终反映服务器数据,您应该没问题。