苦苦挣扎于Redux动作创作者的角色

时间:2017-06-21 08:21:54

标签: redux react-redux

我努力想要得到一个正确的概念,即行动"行动"。它更像是一个简单的消息,代表用户界面中发生的事情,仅此而已,或者是一个持有所有新状态的胖记录?

在我阅读的Redux示例中,操作总是像操作一样简单的CRUD。例如,在添加TODO时,视图按钮事件处理程序(或者我应该说是TODO控制器)创建一个ADD_TODO操作,该操作已包含一个带有新标识符的完整待办事项对象。减速器仅插入数据。减速器不是聪明的"。

但是,这会导致控制器有很多逻辑来计算操作的数据。这对于一个简单的TODO应用程序来说很好,但在更复杂的应用程序中,很多"业务逻辑"将包含在这些控制器中,而不是在reducers中(后者只执行简单的CRUD操作,而这些操作总是相同的。)

因此,如果控制器在创建操作时崩溃,则根本不会记录操作,并且操作记录是Redux的主要卖点之一。

使用复杂代码创建操作以设置操作数据的准则是什么?我应该把try / catch放在这些动作创建器周围,并使用另一个日志记录系统吗?或者我应该使用thunk,将复杂的动作创建分成两个动作(如果发生错误,则为3,就像处理异步API调用一样)?

谢谢, 彼得

2 个答案:

答案 0 :(得分:1)

为您做了一些澄清。

首先,除了type字段之外,没有关于哪些操作必须包含的具体规则,或者逻辑的大部分是否应该在动作创建者或减速器中。有一个只有{type : "UPDATE_STUFF"}的动作并且让reducer完成所有工作,或者让动作创建者生成新状态而减速器只做return {...state, ...action.payload},这是完全有效的。我在博客文章Redux FAQ on where to put business logicIdiomatic Redux: The Tao of Redux, Part 2 - Practice and Philosophy,“动作语义”和“粗细减速器”部分讨论了两种方法的优缺点和权衡。引自己的帖子:

  

在行动创造者中加入更多逻辑与在减速器中加入更多逻辑之间存在有效的权衡。我最近看到的一个好处是,如果你在减速器中有更多的逻辑,这意味着如果你是时间旅行调试(这通常是一件好事),可以重新运行更多的东西。

     

我个人倾向于同时在两个地方放置逻辑。我写动作创建者需要花时间来确定是否应该分派动作,如果是,那么内容应该是什么。但是,我也经常编写相应的reducers来查看动作的内容并执行一些复杂的状态更新作为响应。

     

我通常会尽量减少返回{...state, ...action.payload}的地方数量。如果我在更新表单中的多个可能字段并且不想为每个字段编写单独的updateName / updateAge / updateWhatever处理程序,那么这种方法肯定是有用的。< / p>      

我想说两者都不是更具“惯用性”并且是完全有效的选择,但是在减速器中存在更多逻辑错误的一些好处。

所以, 可以使用“智能”缩减器,我在"Practical Redux" tutorial series中有一些复杂缩减器逻辑的例子。

错误和崩溃将成为一个问题,无论它们是出现在动作创建者还是减少者身上。事实上,如果减速器中存在未被捕获的错误,我相信该动作仍然无法在Redux DevTools中正确记录。

也没有关于是否分派单个操作或多个“构成交易的子操作”的具体规则。我在帖子Idiomatic Redux: Thoughts on Thunks, Sagas, Abstraction, and Reusability中对此进行了一些讨论。

最后,根据问题标题,您可能还想阅读我的帖子Idiomatic Redux: Why use action creators?

答案 1 :(得分:1)

在谈论“行动”时,我不认为CRUD是正确的词。您应该将减速器视为变换。操作是业务逻辑,其中“有效负载”是转换所需的特定信息。

简化是明智的,因为它们使用现有状态来计算下一个状态。

你是什么意思?

  

......很多“业务逻辑”将包含在这些控制器中......

当您谈论“复杂代码”和“尝试/捕获”时..如果您想使用API​​,则应使用redux-auto

来自documantasion:

redux-auto只是通过允许您创建一个返回promise的“action”函数来修复此异步问题。伴随你的“默认”功能动作逻辑。

  1. 不需要其他Redux异步中间件。例如thunk,promise-middleware,saga
  2. 轻松允许您将承诺传递给redux并让它为您管理
  3. 允许您将外部服务呼叫与其转换位置共同定位
  4. 命名文件“init.js”将在应用启动时调用一次。这适用于从服务器开始加载数据
  5. 这个想法是让每个action in a specific file。将文件中的服务器调用与“pending”,“fulfilled”和“rejected”的reducer函数共同定位。这使得处理承诺非常容易。

    它还会自动将helper object(called "async")附加到您所在州的原型,允许您在用户界面中跟踪请求的转换。

    希望这有帮助