Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/460.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 存储乐观更新的操作是Redux/Flux中的一个好方法?_Javascript_Reactjs_Flux_Redux - Fatal编程技术网

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

Javascript 存储乐观更新的操作是Redux/Flux中的一个好方法?,javascript,reactjs,flux,redux,Javascript,Reactjs,Flux,Redux,我一直在使用React+Flux应用程序中的乐观更新,看到了两件事: 当存在一些未完成的操作时,如果用户试图关闭窗口会发生什么情况。例如,在Facebook中,即使没有真正持久化,也会在墙上显示一条消息(乐观更新就是这样做的,对用户来说是一个响应更快的应用程序)。但是,如果用户在墙上张贴帖子并立即关闭应用程序(在注销或关闭窗口时),帖子可能会失败,他不会被提醒 我不喜欢存储管理自己的实体(例如消息)的想法,也不喜欢为持久化消息而触发的操作(加载、成功、失败?)。它把东西混在一起 因此,我对此进行

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

  • 当存在一些未完成的操作时,如果用户试图关闭窗口会发生什么情况。例如,在Facebook中,即使没有真正持久化,也会在墙上显示一条消息(乐观更新就是这样做的,对用户来说是一个响应更快的应用程序)。但是,如果用户在墙上张贴帖子并立即关闭应用程序(在注销或关闭窗口时),帖子可能会失败,他不会被提醒
  • 我不喜欢存储管理自己的实体(例如消息)的想法,也不喜欢为持久化消息而触发的操作(加载、成功、失败?)。它把东西混在一起
  • 因此,我对此进行了研究,并创建了一个ActionStore,以管理由组件触发的操作的状态。源代码和现场演示

    它的工作原理大致如下:

  • 组件层次结构的根(redux中的容器)获取一个新动作的nextId并将其传递给他的孩子般的道具(这很难看)
  • 子组件触发一个操作:它保留actionId,并在之后将其请求到存储区并调用操作创建者
  • 动作创建者创建一个新动作,并向中间件返回一个函数
  • 该操作返回的函数通过API调用创建一个新的承诺,并分派一个XX_START类型的操作
  • ActionStore侦听XX_开始操作并保存它
  • 子组件接收新状态并找到具有保存id的操作,并询问其当前情况:加载、成功或失败
  • 我这样做主要是为了将“实体”的状态与操作的状态分开,但也允许使用相同的负载执行重新触发操作(如果服务器暂时关闭或用户信号松动,当我们收到500个响应状态时,这可能很有用)

    此外,在用户注销或关闭窗口之前,有一个操作存储区可以很容易地询问它们是否是挂起的操作

    注意:我正在使用一个单一的应用程序页面web应用程序来对抗RESTAPI,我不认为在服务器端渲染中使用它

    这是一个可行的选择创建ActionStore还是我正在打破一些Redux/Flux的基础? 这可能会终止热装和时间旅行的可能性


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

    对于未来可能有点困惑的读者:我们不再称这些功能为“存储”,而是称之为“存储”。所以问题是关于

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

    我认为在Redux中实现乐观更新的方法与您的方法类似,这反过来又受到了您的启发。其思想是,您应该编写一个函数,该函数接受一个减速机(和一些选项)并返回一个减速机:

    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)
        };
      }
    }
    
    现在,它累加
    历史记录
    字段中的所有操作

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

    • 通过ID跟踪挂起的异步操作,并在看到状态为“请求”的操作时开始记录历史记录
    • 当它收到状态为“完成”的操作时,重置历史记录
    • 当它接收到状态为“失败”的操作时,调整历史记录,使其不包括状态为“请求”的初始操作,重新运行reducer以重新计算当前状态,就好像请求从未发生过一样。
    当然,我还没有提供实现,但这应该让您了解如何以Redux方式实现乐观更新


    更新:根据OP的评论,似乎正是如此。

    感谢Dan的帮助。我不明白你为什么说减速器必须重新计算当前状态,就好像请求从未发生过一样。如果我有一个React组件通过加载旋转触发了操作,我想在操作失败时显示一条错误消息。如果我失败了,我将如何做到这一点?事实上,我正在使用一个基于的中间件,我认为这是一个很好的方法,不是吗?“我不明白为什么你说减速器必须重新计算当前状态,就好像请求从未发生过一样。”我认为问题是关于乐观的更新。使用乐观更新,如果请求失败,您希望回滚在请求开始时所做的任何更改。显示错误消息与乐观更新无关;例如,你是对的,我把概念弄糊涂了。我会考虑一下你的建议,然后再回来实施。我也会看看,也许这就是我一直在寻找的。简单地说,我认为显示错误消息与乐观更新密切相关。如果我们想要实现响应,ToDo项不能简单地从屏幕中弹出。是的,
    redux optimist
    看起来与我试图描述的完全一样。