首页 > 解决方案 > React-Redux 更新和重定向逻辑

问题描述

我有数据结构 Student、Class 和 Registrant。Registrant 是班级和学生之间的纽带:

Registrant 
-----------
StudentId
ClassId

当你可以从中选择时,我还有一个辅助数据源——称之为PotentialStudents。

最终用户可以浏览潜在学生列表,并为他们注册课程。

如果潜在学生记录不存在学生记录,我需要创建一个,否则我需要获取获取的记录。我可以知道这一点,因为 PotentialStudentId 是 Student 中的一个字段,但 Student 和 PotentialStudent 之间没有真正的关系——它们来自不同的数据库,实际上是不同的数据形状。

无论如何,这就是设置我的问题。我需要一个函数来“createOrFetchStudent”,然后将它们发送到 RegistrationDetail 表单。

我的问题是,这应该如何在 react-redux 中完成?

我可以 -

尝试分派 save/fetch 并在完成时发出信号,然后重定向,但它有点混乱

let student = useSelector(state => state.createdOrFetchedStudent);

useEffect(() => {
  if(student) {
    location.push("/registration", {studentId: student.id});
  }
}, [student]); 

onRegisterDetailClick = (potentialStudent) => {
  // redux-thunk action that does multiple API calls
  dispatch(createOrFetchStudent(potentialStudent));
}

还是从行动中完成所有工作?

onRegisterDetailClick = (potentialStudent) => {
  dispatch(createOrFetchStudentAndThenRedirect(potentialStudent));
}

但是不知道在 redux 操作中使用位置是否可以。

我的其他想法-

我可以将回调传递给操作

onRegisterDetailClick = (potentialStudent) => {
  dispatch(createOrFetchStudent(
    potentialStudent,
    (student) => { location.push("/registration", { studentId: student.id } ); })
  );
}

我可以从 thunk 方法返回分配的数据并等待它

onRegisterDetailClick = async (potentialStudent) => {
  let student = await dispatch(createOrFetchStudent(potentialStudent));
  location.push("/registration", { studentId: student.id } ); }
}

这些解决方案似乎都不是很好。这些解决方案中的任何一个都可以接受还是有更好的方法?

标签: reactjsredux

解决方案


保持你的动作创建者纯函数是一个好主意(尽管它不像减速器那样严格要求)。
它将提高可测试性并使您的代码更易于理解。将副作用(如位置更改)放入 thunk 是完全有效的(您的最后一个示例)。
如果您仍然对此感到不舒服(我有点理解为什么),您可以尝试使用 redux-saga,它可以让您在一个地方管理所有副作用并保持您的功能纯净。您可以在 redux文档
中阅读有关每种方法的更多信息


推荐阅读