用于乐观更新的操作存储是 Redux/Flux 中的一个好方法吗?

2024-01-03

我一直在 React+Flux 应用程序中进行乐观更新,并看到了两件事:

  1. 如果用户在存在某些未完成的操作时尝试关闭窗口,会发生什么情况。例如,在 Facebook 中,即使没有真正持久化,消息也会出现在墙上(这就是乐观更新的作用,对用户来说是一个响应更快的应用程序)。但是,如果用户在留言墙上发帖并立即关闭应用程序(注销或窗口关闭时),则该发帖可能会失败并且不会收到警报。
  2. 我不喜欢商店管理自己的实体(例如消息)的想法以及为持久化消息而触发的操作的情况(加载、成功、失败?)。它混合了东西。

所以我致力于此并创建一个行动商店管理组件触发的操作的状态。Here is https://github.com/gabrielgiussi/redux_actionsStore源代码和here is http://www.googledrive.com/host/0Bw73nZfYKsXNfkY4T2xWLTktQW8tWV92UVBULUNzQXpuazdRYTVicEhpQlFXcW1NMTVlalk现场演示。

它的工作原理或多或少像这样:

  1. 组件层次结构的根(redux 中的容器)获取新操作的 nextId 并将其像 props 一样传递给他的子级(这很丑陋)。
  2. 子组件触发一个操作:它保留 actionId,以便在之后将其请求到存储并调用操作创建者。
  3. 动作创建者创建一个新的动作并向中间件返回一个函数。
  4. 从 Action 返回的函数通过 API 调用创建一个新的 Promise,并分派 XX_START 类型的操作。
  5. ActionStore 监听 XX_START 操作并保存它。
  6. 子组件接收新状态并找到具有保存的 id 的操作并询问当前情况:加载、成功或失败。

我这样做主要是为了将“实体”的状态与操作的状态分开,但也允许使用相同的负载重新触发操作(当我们收到 500 响应状态时,如果服务器暂时关闭或如果用户丢失信号)。

此外,拥有操作存储可以在用户注销或关闭窗口之前轻松询问它们是否是待处理的操作。

注意:我正在针对 Rest API 使用单应用程序页面 Web 应用程序,我不认为在服务器端渲染上使用它

创建 ActionStore 是一个可行的选择,还是我破坏了一些 Redux/Flux 基础? 这可能会结束使用 React 热重载和时间旅行的可能性吗?

你应该毫不留情地回答,我可能做了很多丑陋的事情,但我正在学习 React/Redux。


对于可能有点困惑的未来读者:我们不再称这些函数为“存储”:我们称它们为“存储”reducers http://rackt.github.io/redux/docs/basics/index.html。所以问题是关于一个记住动作的减速器 https://github.com/gabrielgiussi/redux_actionsStore/blob/2e948b8ea616ea9f1289d0b6e5d2f60d82545f11/js/src/common/ActionStore.js.

就我个人而言,我不喜欢你在那里建议的方法。您将逻辑放入操作中并为此使用继承。相反,Redux 将操作规定为没有逻辑的普通对象。他们不应该“知道”如何更新某些状态,也不应该保留它——相反,他们应该描述发生了什么。

我认为在 Redux 中实现乐观更新的方法与您的方法类似在 Redux 中实现撤销 https://github.com/omnidan/redux-undo,这反过来又受到启发榆树建筑 https://github.com/evancz/elm-architecture-tutorial/。这个想法是,您应该编写一个函数,它接受一个减速器(和一些选项)并返回一个减速器:

function optimistic(reducer) {
  return function (state, action) {
    // do something?
    return reducer(state, action);
  }
}

你可以像普通的减速器一样使用它:

export default combineReducers({
  something: optimistic(something) // wrap "something" reducer
})

现在它只是将状态和操作传递给reducer它会包装,但它也可以“记住”动作:

function optimistic(reducer) {
  return function (state = { history: [] }, action) {
    // do something with history?
    return {
      history: [...state.history, action],
      present: reducer(state.history[state.history.length - 1], action)
    };
  }
}

现在它累积了所有动作history field.

同样,这本身并不是很有用,但您可能会看到如何实现这样的高阶减速器:

  • 通过 ID 跟踪待处理的异步操作,并在看到带有以下内容的操作时开始记录历史记录status: 'request';
  • 当它收到一个动作时status: 'done',重置历史记录;
  • 当它收到一个动作时status: 'fail',调整历史记录以不包括初始操作status: 'request' and 重新运行减速器以重新计算当前状态,就好像请求从未发生过一样。

当然,我没有提供实现,但这应该让您了解如何以 Redux 方式实现乐观更新。

更新:根据OP的评论,还原乐观主义者 https://github.com/ForbesLindesay/redux-optimist似乎正是这样做的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用于乐观更新的操作存储是 Redux/Flux 中的一个好方法吗? 的相关文章

  • 如何使用 jQuery 添加/附加到外部 JSON 文件

    我有一个 json 文件 我想构建一个表单 允许我在文件中添加 编辑元素 是否有 jQuery 函数 方法允许我在外部 json 文件中发布和追加元素 不确定这是否有帮助 但当前的 json 结构如下 cast director genre
  • 使用 ReactJS 突出显示文本

    我试图突出显示与查询匹配的文本 但我不知道如何让标签显示为 HTML 而不是文本 var Component React createClass highlightQuery function name query var regex ne
  • Javascript dispatchEvent click 在 IE9 和 IE10 中不起作用

    我正在尝试在 ExtJs 中构建应用程序时模拟鼠标事件 例如单击 鼠标悬停等 我使用下面的代码来模拟点击 function triggerEvent element eventName if document createEvent var
  • 停止 ASP.NET 按钮的页面重新加载

    NET 应用程序中 我插入了一个调用 Javascript 函数的按钮 OnClientClick事件 和 VB NET 函数 OnClick event
  • 如何向 DOM 添加支持 Angular 的元素?

    我想以编程方式添加一些支持 Angular 的 DOM 元素 实际上 我可能需要添加自定义组件 我该怎么做 这是一个简单的小提琴来演示这个问题 http jsfiddle net ZJSz4 2 http jsfiddle net ZJSz
  • 在 Angular 2+ 中进行 DOM 操作的正确方法

    我知道有一些类似的问题 但没有人回答我的问题 基本上 以角度方式操作 DOM 的正确方法是什么 比如说我有这个 html
  • Jquery 选择器中的冒号

    我最近将 jquery 从 1 4 更新到 2 1 并开始出现错误 在我的代码中 我有一部分通过 id 选择元素 jQuery id name 这会产生一个错误 但是之前没有错误 1 4 如果我转义冒号 错误就会消失 他们在最新版本中添加了
  • 浏览器中的javascript:异步任务执行模型

    我正在尝试集中注意力并了解 javascript 异步在单线程浏览器环境中的工作原理 作为异步 我们可以同时处理计时器和 xhr 请求 现在假设我有类似下面的东西 function doStuff for var i 0 i lt 1000
  • JavaScript switch 语句是线性的还是恒定时间的?

    我的网站上有以下 JavaScript 以便在执行某些特定搜索时 答案会被硬编码到特定页面 function redirect var input document getElementById searchBox value toLowe
  • 在 JQueryUI 小部件的 QUnit 测试中测试可见性

    这对于其他人来说可能是显而易见的 但我没有通过搜索找到它 所以在这里发布问题和一个可能的答案 背景 使用自定义 JQuery UI 小部件小部件工厂 http jqueryui com widget 在小部件中 某些元素根据其他数据 选项隐
  • 如何通过 Web-Workers 传递自定义类实例?

    由于 Web Worker JSON 在线程之间序列化数据 因此这样的方法不起作用 worker js function Animal Animal prototype foobar function self onmessage func
  • 如何将多种语言设置放入单个 .clang-format 文件中

    我想为 java javascript 和 c 创建一个 clang 格式 我知道如何转储单一语言的示例配置 但不知道如何合并这 3 个配置文件 有关如何将多种语言配置放入单个文件中的示例 BasedOnStyle LLVM IndentW
  • 如何在 html5 中加载部分 html? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 询问我们的问题推荐或查找工具 库或最喜欢的场外资源与 Stack Overflow 无关 因为它们往往会吸引固执己见的答案和垃圾邮件 反而
  • Select2 触发器(“更改”)创建无限循环

    假设页面上有两个 select2 元素 都使用 onChange 为了以编程方式在一个 select2 元素中设置一个值 您可以使用 id1 val xyz trigger change 如果您在这两个元素之一中进行选择时想要将另一个元素重
  • React:使用索引作为列表中项目的键

    使用索引作为列表中项目的键有哪些陷阱 在添加或删除列表中的元素时 React 更改检测或任何意外的列表更新是否存在任何性能缺陷 我已经阅读了几篇有关此的文章 但仍然没有弄清楚 请参考codepen http shorturl at grBM
  • 函数声明可以出现在 JavaScript 的语句内部吗?

    请考虑将官方 ECMAScript 规范作为您答案的来源 而不是特定浏览器供应商发布的文档 我知道 Mozilla 用 函数语句 扩展了它的 JavaScript 实现 因此 根据 ECMAScript 规范 因此 其中定义的语法产生式 这
  • jquery ui 自动完成添加跨度

    我在 div 上使用 jQuery 自动完成 但我得到了 jquery 自动添加的额外范围 span class ui helper hidden accessible search test span 如何防止创建此跨度 我通过添加 CS
  • 返回语句后的声明

    function f return f1 function f1 return 5 f returns 5 为什么这有效 之后声明局部函数有什么好处return 这是好的做法吗 它之所以有效 是因为函数声明都是由解释器在第一次传递时评估的
  • 使用与 eval 相反的括号表示法

    我有以下内容 var module function console log module ran var someString module string TypeError object is not a function eval s
  • 理解“窗口”对象[重复]

    这个问题在这里已经有答案了 可能的重复 JS 窗口全局对象 https stackoverflow com questions 10035771 js window global object 如何window对象工作 我知道它是顶级对象并

随机推荐

  • IIS 7.5 在哪里记录错误?

    IIS 7 5 在哪里记录错误 事件查看器 日志档案 我收到一个非常不具体的内部 500 错误 我想了解更多 我正在运行 PHP 我做了什么最后一条评论 http forums iis net t 1169733 aspx在这个帖子上说 但
  • 检测直角三角形的C程序

    如果给我坐标系中的 100 个点 我必须找出这些顶点中是否存在直角三角形 有没有一种方法可以检测这些顶点中的直角三角形 而不必选择所有 3 个顶点对 然后对它们应用毕达哥拉斯定理 有更好的算法吗 谢谢你的帮助 这是一个O n 2 log n
  • 对绑定到 DataTable 的 GridView 进行排序

    我有一个存储库 其中包含我正在处理的这个项目的所有 LINQ 查询 我能够将 LINQ 结果获取到 DataTable 并将其绑定到 gridview 以显示数据 现在我需要使 gridview 可排序 我已经设定AllowSorting
  • 如何确定 Git 中合并提交的第一个父级

    我正在阅读有关使用的差异 vs git 中的运算符 我遇到了这个问题Git 中的 HEAD 和 HEAD 有什么区别 https stackoverflow com q 2221658 2498327 在谷歌搜索后 我在网上找不到一个很好的
  • 当我有触摸事件处理程序时,为什么我的鼠标事件处理程序不工作?

    我的一些最终用户拥有触摸屏 其他用户则拥有 PC 在触摸屏上 PreviewMouseUp Down与触摸事件处理程序一起触发 导致重复行为 在 PreviewMousUp Down 中编写的函数被执行两次 所以我的示例按钮 XAML
  • 当涉及两个输入时,jQuery 模糊不断触发

    我在 Google 和 Stack Overflow 上搜索了一段时间 但找不到与此相关的任何内容 我有多个输入文本字段 当模糊时 它们会向服务器调用 jQuery AJAX 函数 它几乎可以完美地工作 问题是 如果我专注于一个文本输入 然
  • 为什么 Set 与 Proxy 不兼容?

    JavaScriptSet https developer mozilla org en docs Web JavaScript Reference Global Objects Set似乎与 JavaScript 完全不兼容proxies
  • Pymongo 连接远程机器超时

    我有一个在 AWS EC2 上运行的 Bitnami MEAN 堆栈 我正在尝试使用 PyMongo 从远程计算机进行连接 from pymongo import MongoClient conn MongoClient mongodb u
  • Automapper:忽略条件

    是否可以根据源属性的值忽略映射成员 例如 如果我们有 public class Car public int Id get set public string Code get set public class CarViewModel p
  • 可以要求我的事件处理程序立即返回吗?

    我正在编写一个 NET 库 其中一个类包含库用户需要订阅的事件 是否可以要求这些事件的处理程序的实现快速返回 或者这是一个有共同解决方案的常见问题吗 如果处理程序花费很长时间 这不会是致命的 但如果处理程序花费的时间超过大约半秒 事情就会开
  • Angular 5 - 添加动态路由但不路由

    我创建了一个新项目 并向路由模块添加了一些代码以进行动态路由 路由模块代码如下 import NgModule from angular core import Routes RouterModule Router from angular
  • SSRS 和 PowerShell:获取 Excel 格式的报告

    我正在尝试让 PowerShell 向我们的 SSRS 服务器发送 Web 请求并捕获结果 我已经使用了撞墙rs FORMAT EXCELSSRS url 字符串中的参数 我有以下内容 首先 初始化凭据 User MYDOMAIN MyUs
  • jquery 插件在其他公共函数中调用公共函数

    我定义了我的插件基于http docs jquery com Plugins Authoring http docs jquery com Plugins Authoring function var methods init functi
  • 使用 httplib 进行不完整读取

    我在从特定网站获取 RSS 提要时一直遇到问题 我最终编写了一个相当丑陋的程序来执行此功能 但我很好奇为什么会发生这种情况以及是否有更高级别的接口正确处理此问题 这个问题并不是真正的问题 因为我不需要经常检索提要 我已经阅读了一个捕获异常并
  • AngularJS Protractor E2E 模拟

    我有一个 Angular SPA 从节点后端检索其数据 由于节点项目完全覆盖了测试 我想模拟 Angular HTTP 调用 我不想开始讨论一般的功能 冒烟测试 谢谢 我想要的是 像这样 Api injector get Api sinon
  • 按位 XOR(异或)是什么意思?

    我试图理解 C 或一般情况下的二元运算符 特别是 异或 http msdn microsoft com en us library zkacc7k1 aspx 例如 给定一个正整数数组 除了一个出现奇数次的数字外 所有数字都出现偶数次 在
  • nodejs socket.io 在函数循环内发出

    我想通过循环内的 socket io 发出 为此 我制作了一个运行良好的触发器 但在每个触发器中我调用 socket emit 并且只有第一个发出有效 这是服务器代码 var server require http createServer
  • 从动态 PHP 页面生成 HTML 静态页面 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个脚本来在运行时从动态内容生成静态 HTML 页面 我基本上想做的就是保存那些缓存那些ht
  • 用于提取 HTML 图像属性的正则表达式

    我需要一个正则表达式模式来提取图像标签的所有属性 众所周知 存在大量格式错误的 HTML 因此该模式必须涵盖这些可能性 我正在看这个解决方案https stackoverflow com questions 138313 how to ex
  • 用于乐观更新的操作存储是 Redux/Flux 中的一个好方法吗?

    我一直在 React Flux 应用程序中进行乐观更新 并看到了两件事 如果用户在存在某些未完成的操作时尝试关闭窗口 会发生什么情况 例如 在 Facebook 中 即使没有真正持久化 消息也会出现在墙上 这就是乐观更新的作用 对用户来说是