在线文档教程

Redux FAQ:操作(Actions)

Redux FAQ:操作(Actions)

目录

  • 为什么要输入一个字符串,或者至少可以序列化?为什么我的动作类型是常量?

  • 减速器和动作之间总是存在一对一的映射关系吗?

  • 我如何表示“副作用”,如AJAX调用?为什么我们需要像“action creators”,“thunk”和“middleware”这样的东西来做异步行为?

  • 我应该从一个动作创作者连续发送多个动作吗?

操作

为什么type应该是一个字符串,或者至少是可序列化的?为什么我的动作类型是常量?

与状态一样,可序列化操作启用 Redux 的几个定义功能,例如时间旅行调试,以及记录和重放操作。使用类似于a Symboltype值或使用instanceof检查操作本身会破坏这一点。字符串可序列化的,并且易于自我描述,因此更好的选择。请注意,这好的,如果动作供中间件使用使用符号,承诺,或其他非序列值的操作。动作只需要在实际到达商店时被序列化并传递给减速器。

由于性能原因,我们无法可靠地执行可序列化操作,因此 Redux 仅检查每个操作是否为普通对象,并且该操作是否type已定义。其余的由您决定,但是您可能会发现保持所有序列化操作有助于调试和重现问题。

封装和集中常用代码段是编程中的一个关键概念。尽管无处不在手动创建动作对象并手动编写每个type值,但定义可重用常量使维护代码更加容易。如果你把常量放在一个单独的文件中,你可以检查你的import语句是否有错别字,这样你就不会意外地使用错误的字符串。

更多信息

文档

  • 减少样板

减速器和动作之间总是存在一对一的映射关系吗?

不是的。我们建议您编写独立的小型还原器函数,每个函数负责更新特定的状态片。我们称这种模式为“减速器组成”。一个给定的行动可以被全部,部分或全部处理。这使得组件与实际数据更改分离,因为一个动作可能会影响状态树的不同部分,并且组件不需要知道这一点。一些用户确实选择将它们更紧密地绑定在一起,比如“ducks”文件结构,但默认情况下肯定没有一对一的映射,并且只要你觉得你想要的时候你应该跳出这样的范式在许多减速器中处理动作。

更多信息

文档

  • 基础知识:减速器

  • Recipes: 构造减速器

讨论

  • Twitter: most common Redux misconception

我如何表示“side effects”,如 AJAX 调用?为什么我们需要像“action creators”,“thunk”和“middleware”这样的东西来做异步行为?

这是一个漫长而复杂的话题,关于如何组织代码以及应该采用什么方法提出了各种各样的意见。

任何有意义的 Web 应用程序都需要执行复杂的逻辑,通常包括异步工作,例如制作 AJAX 请求。该代码不再纯粹是其输入的函数,并且与外界的交互被称为“side effects”

Redux 的灵感来自于函数式编程,开箱即用,无法执行副作用。特别是减速机函数必须始终是纯粹的函数(state, action) => newState。但是,Redux 的中间件可以拦截已分派的操作并在其周围添加其他复杂行为,包括副作用。

一般来说,Redux 建议具有副作用的代码应该是动作创建过程的一部分。尽管该逻辑可以在 UI 组件内执行,但通常将该逻辑抽取为可重用的函数是有意义的,以便可以从多个位置调用相同的逻辑 - 换句话说,就是动作创建器函数。

最简单也是最常用的方法是添加 Redux Thunk 中间件,该中间件可让您为动作创建者编写更复杂和异步的逻辑。另一个广泛使用的方法是 Redux Saga,它允许您使用生成器编写更多的同步代码,并且可以在Redux应用程序中充当“后台线程”或“守护进程”。另一种方法是 Redux Loop,它通过允许你的 reducer 声明副作用来响应状态变化并使它们分开执行来颠倒过程。除此之外,还有许多其他社区开发的图书和想法,每个都有自己的副作用应该如何管理。

更多信息

文档

  • 高级: 异步操作

  • 高级:异步流程

  • 高级:中间件

文章

讨论

我应该从一个动作创作者连续发送多个动作吗?

没有关于如何构建你的行为的具体规则。使用像 Redux Thunk 这样的异步中间件当然可以实现诸如在一行中分派多个不同但相关的动作,分派动作以表示 AJAX 请求的进展,基于状态有条件地分派动作,或者甚至分派动作并立即检查更新的状态之后。

一般来说,要问这些行为是相关的但是独立的,还是应该实际表现为一个行为。对自己的情况做些有意义的事情,但试着平衡减速器的可读性和动作日志的可读性。例如,包含整个新状态树的操作将使您的 reducer 成为一行,但缺点是您现在没有关于变化发生的原因的历史记录,所以调试变得非常困难。另一方面,如果你在一个循环中发出动作以保持细化,这表明你可能想引入一个以不同方式处理的新动作类型。

尽量避免在您关心性能的地方连续多次同步调度。还有一些插件和方法可以批量发送。

更多信息

文档

  • FAQ: 性能 - 减少更新事件