关于javascript:为什么使用Redux而不是Facebook Flux?

Why use Redux over Facebook Flux?

我已经阅读了这个答案,减少了样板文件,看了几个Github示例,甚至尝试了一点Redux(Todo应用程序)。

据我所知,与传统的MVC体系结构相比,官方的ReduxDoc动机提供了优点。但它并不能回答这个问题:

为什么要在Facebook流量上使用Redux?

这仅仅是编程风格的问题吗:功能性与非功能性?或者问题出在Redux方法后面的能力/开发工具中?也许缩放?还是测试?

如果我说redux对于来自函数语言的人来说是一种流量,那我是对的吗?

为了回答这个问题,您可以比较实现的复杂性,Redux在Flux和Redux上的动机点。

以下是官方Redux Doc动机的激励点:

  • 处理乐观更新(据我所知,这几乎不取决于第5点。在facebook flux中很难实现吗?)
  • 在服务器上渲染(Facebook Flux也可以这样做。与Redux相比有什么好处吗?)
  • 在执行路由转换之前获取数据(为什么它不能在Facebook流量中实现?有什么好处?)
  • 热重新加载(可以使用React热重新加载。为什么我们需要Redux?)
  • 撤消/重做功能
  • 还有其他问题吗?就像持续状态…

  • 还原作者!好的。

    Redux和Flux没有什么不同。总体来说,它具有相同的体系结构,但Redux能够通过使用功能组合(Flux使用回调注册)来减少一些复杂性。好的。

    redux中没有根本的区别,但我发现它使某些抽象更容易实现,或者至少可以实现,而这在flux中很难实现或者不可能实现。好的。还原剂成分

    例如,分页。我的flux+react路由器例子处理分页,但是代码太糟糕了。糟糕的一个原因是,Flux使跨存储重用功能变得不自然。如果两个存储需要处理分页以响应不同的操作,那么它们要么需要从公共基本存储继承(坏!当您使用继承时,您将自己锁定到一个特定的设计中),或者从事件处理程序中调用一个外部定义的函数,这将需要以某种方式操作Flux存储的私有状态。整个事情是混乱的(尽管肯定是在可能的范围内)。好的。

    另一方面,由于还原剂的组成,还原分页是自然的。它一直是减速器,所以您可以编写一个减速器工厂,生成分页减速器,然后在减速器树中使用它。之所以这么简单,关键是因为在Flux中,存储是平面的,但是在Redux中,Reducer可以通过函数组合嵌套,就像React组件可以嵌套一样。好的。

    这种模式还可以实现非常好的功能,比如无需用户代码撤消/重做。你能想象把undo/redo插入到一个flux应用程序中是两行代码吗?几乎没有。有了Redux,由于Redux的组成模式,它又出现了。我需要强调的是,这并不是什么新鲜事,这是ELM架构中开创和详细描述的模式,ELM架构本身受到流量的影响。好的。服务器呈现

    人们已经用flux在服务器上进行了很好的渲染,但是看到我们有20个flux库,每个库都试图使服务器渲染"更容易",也许flux在服务器上有一些粗糙的边缘。事实上,Facebook并没有做太多的服务器渲染,所以他们并不十分关心它,而是依靠生态系统使其变得更容易。好的。

    在传统的潮流中,商店是单件的。这意味着很难为服务器上的不同请求分离数据。不可能,但很难。这就是为什么大多数Flux库(以及新的Flux实用程序)现在建议您使用类而不是单例,这样您就可以根据请求实例化存储。好的。

    在flux中仍然需要解决以下问题(您自己或在您最喜欢的flux库(如flummox或alt)的帮助下):好的。

    • 如果存储是类,如何根据请求使用分派器创建和销毁它们?我什么时候登记商店?
    • 如何对存储中的数据进行水合物处理,然后在客户机上对其进行再水合物处理?我需要为此实现特殊的方法吗?

    诚然,Flux框架(不是普通的Flux)有解决这些问题的方法,但我发现它们过于复杂。例如,FlumMax要求您在商店中实现serialize()deserialize()。alt通过提供自动在JSON树中序列化状态的takeSnapshot()来解决这个问题。好的。

    Redux更进一步:因为只有一个商店(由许多Reducer管理),所以您不需要任何特殊的API来管理(再)水化。你不需要"冲洗"或"水合物"商店只有一个商店,你可以读取它的当前状态,或者创建一个新的商店有一个新的状态。每个请求都会得到一个单独的存储实例。阅读有关使用Redux进行服务器渲染的更多信息。好的。

    同样,这是一个在Flux和Redux中都可能出现的情况,但是Flux库通过引入大量的API和约定来解决这个问题,而且Redux甚至不必解决这个问题,因为由于概念简单,它一开始就没有这个问题。好的。开发人员经验

    实际上,我并没有打算让Redux成为一个流行的Flux库——我在写这篇文章的时候,正在写一篇关于用时间旅行进行热重载的欧洲反应演讲。我的一个主要目标是:通过划掉动作,可以在运行中更改reducer代码,甚至可以"更改过去",并看到重新计算的状态。好的。

    >好的。<P>我还没有看到一个能做到这一点的flux库。React Hot加载器也不允许您这样做,事实上,如果您编辑Flux存储,它就会中断,因为它不知道如何处理它们。好的。<P>当Redux需要重新加载Reducer代码时,它调用<wyn>replaceReducer()</wyn>,并且应用程序使用新代码运行。在flux中,数据和函数都被flux存储缠住了,所以您不能Redux拥有丰富而快速发展的生态系统。这是因为它提供了一些扩展点,如中间件。它的设计考虑了日志记录、承诺支持、可观察性、路由、不可变开发检查、持久性等用例。并不是所有这些工具都有用,但是能够访问一组可以轻松组合在一起工作的工具是很好的。好的。简单性

    Redux保留了Flux的所有优点(动作的记录和重放、单向数据流、依赖性突变),并且在不引入调度程序和存储注册的情况下添加了新的优点(轻松撤消重做、热重加载)。好的。

    保持简单是很重要的,因为在实现更高级别的抽象时,它可以让您保持清醒。好的。

    与大多数Flux库不同,ReduxAPI表面很小。如果您删除了开发人员的警告、注释和健全性检查,那么这是99行。没有需要调试的复杂异步代码。好的。

    实际上,你可以阅读它并理解所有的redux。好的。

    另请参阅我关于使用Redux与Flux相比的缺点的回答。好的。好啊。


    在Quora,有人说:

    First of all, it is totally possible to write apps with React without
    Flux.

    另外,我创建的这个可视化图表显示了两者的快速视图,可能是对那些不想阅读整个解释的人的快速回答:Flux vs Redux

    但如果你还想知道更多,继续读下去。

    I believe you should start with pure React, then learn Redux and Flux.
    After you will have some REAL experience with React, you will see
    whether Redux is helpful for you or not.

    Maybe you will feel that Redux is exactly for your app and maybe you
    will find out, that Redux is trying to solve a problem you are not
    really experiencing.

    If you start directly with Redux, you may end up with over-engineered
    code, code harder to maintain and with even more bugs and than without
    Redux.

    从Redux文档:

    Motivation As the requirements for JavaScript single-page applications have become increasingly complicated, our
    code must manage more state than ever before. This state can include
    server responses and cached data, as well as locally created data that
    has not yet been persisted to the server. UI state is also increasing
    in complexity, as we need to manage active routes, selected tabs,
    spinners, pagination controls, and so on.

    Managing this ever-changing state is hard. If a model can update
    another model, then a view can update a model, which updates another
    model, and this, in turn, might cause another view to update. At some
    point, you no longer understand what happens in your app as you have
    lost control over the when, why, and how of its state. When a system
    is opaque and non-deterministic, it's hard to reproduce bugs or add
    new features.

    As if this wasn't bad enough, consider the new requirements becoming
    common in front-end product development. As developers, we are
    expected to handle optimistic updates, server-side rendering, fetching
    data before performing route transitions, and so on. We find ourselves
    trying to manage a complexity that we have never had to deal with
    before, and we inevitably ask the question: Is it time to give up? The
    answer is No.

    This complexity is difficult to handle as we're mixing two concepts
    that are very hard for the human mind to reason about: mutation and
    asynchronicity. I call them Mentos and Coke. Both can be great when
    separated, but together they create a mess. Libraries like React
    attempt to solve this problem in the view layer by removing both
    asynchrony and direct DOM manipulation. However, managing the state of
    your data is left up to you. This is where Redux comes in.

    Following in the footsteps of Flux, CQRS, and Event Sourcing, Redux
    attempts to make state mutations predictable by imposing certain
    restrictions on how and when updates can happen. These restrictions
    are reflected in the three principles of Redux.

    同样来自Redux文档:

    Core Concepts Redux itself is very simple.

    Imagine your app's state is described as a plain object. For example,
    the state of a todo app might look like this:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {
      todos: [{
        text: 'Eat food',
        completed: true
      }, {
        text: 'Exercise',
        completed: false
      }],
      visibilityFilter: 'SHOW_COMPLETED'
    }

    This object is like a"model" except that there are no setters. This
    is so that different parts of the code can’t change the state
    arbitrarily, causing hard-to-reproduce bugs.

    To change something in the state, you need to dispatch an action. An
    action is a plain JavaScript object (notice how we don't introduce any
    magic?) that describes what happened. Here are a few example actions:

    1
    2
    3
    { type: 'ADD_TODO', text: 'Go to swimming pool' }
    { type: 'TOGGLE_TODO', index: 1 }
    { type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_ALL' }

    Enforcing that every change is described as an action lets us have a
    clear understanding of what’s going on in the app. If something
    changed, we know why it changed. Actions are like breadcrumbs of what
    has happened. Finally, to tie state and actions together, we write a
    function called a reducer. Again, nothing magic about it — it's just a
    function that takes state and action as arguments, and returns the
    next state of the app. It would be hard to write such a function for a
    big app, so we write smaller functions managing parts of the state:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    function visibilityFilter(state = 'SHOW_ALL', action) {
      if (action.type === 'SET_VISIBILITY_FILTER') {
        return action.filter;
      } else {
        return state;
      }
    }

    function todos(state = [], action) {
      switch (action.type) {
      case 'ADD_TODO':
        return state.concat([{ text: action.text, completed: false }]);
      case 'TOGGLE_TODO':
        return state.map((todo, index) =>
          action.index === index ?
            { text: todo.text, completed: !todo.completed } :
            todo
       )
      default:
        return state;
      }
    }

    And we write another reducer that manages the complete state of our
    app by calling those two reducers for the corresponding state keys:

    1
    2
    3
    4
    5
    6
    function todoApp(state = {}, action) {
      return {
        todos: todos(state.todos, action),
        visibilityFilter: visibilityFilter(state.visibilityFilter, action)
      };
    }

    This is basically the whole idea of Redux. Note that we haven't used
    any Redux APIs. It comes with a few utilities to facilitate this
    pattern, but the main idea is that you describe how your state is
    updated over time in response to action objects, and 90% of the code
    you write is just plain JavaScript, with no use of Redux itself, its
    APIs, or any magic.


    你最好从丹·阿布拉莫夫的这篇文章开始,他在写Redux时讨论了Flux的各种实现及其权衡:通量框架的演变

    其次,链接到的动机页面并没有真正讨论redux的动机,而是讨论了flux(和react)背后的动机。这三个原则更具体地说是redux,尽管它仍然没有处理与标准Flux体系结构的实现差异。

    基本上,Flux有多个存储,用于计算响应与组件的UI/API交互的状态更改,并将这些更改作为组件可以订阅的事件广播。在Redux中,每个组件只订阅一个存储。在我看来,Redux至少像Redux一样,通过统一(或者像Redux所说的那样减少)返回组件的数据流,进一步简化和统一了数据流,而Flux则专注于统一数据流的另一面——从视图到模型。


    我是一个早期的采用者,使用facebook flux库实现了一个中型单页应用程序。

    由于我的谈话有点晚了,我会指出,尽管我最大的希望是facebook似乎认为他们的flux实现是一个概念的证明,它从来没有得到应有的关注。

    我鼓励您使用它,因为它会暴露出更多的Flux体系结构的内部工作,这是非常有教育意义的,但同时它并没有提供像Redux这样的库所提供的许多好处(这对小项目来说并不重要,但对大项目来说非常有价值)。

    我们决定继续前进,我们将转向Redux,我建议您也这样做;)


    这里是流量减少的简单解释。Redux没有调度程序。它依赖称为Reducers的纯函数。它不需要调度员。每个操作都由一个或多个减速器处理,以更新单个存储。由于数据是不可变的,因此Reducers返回更新storeenter image description here的新更新状态。

    有关更多信息,请参阅Flux vs Redux


    我用Flux工作了很长时间,现在用Redux工作了很长时间。正如丹指出的,这两种建筑并没有那么不同。问题是,Redux使事情变得简单和干净。它教你一些关于易变的东西。例如,通量就是单向数据流的完美例子。分离我们拥有数据的关注点,分离它的操作和视图层。在Redux中,我们有相同的东西,但是我们也学习了不可变和纯函数。


    从2018年年中从extjs(几年)迁移过来的新的react/redux应用程序:

    在沿着redux学习曲线向后滑动之后,我有了同样的问题,我认为纯通量和op一样简单。

    我很快就看到了上面答案中提到的减少流量的好处,并将其应用到我的第一个应用程序中。

    当我再次抓住锅炉盘的时候,我尝试了其他一些国家管理的libs,我发现最好的是复赛。

    它比普通的Redux更直观,它减少了90%的样板文件,并减少了75%的我花在Redux上的时间(我认为图书馆应该做的事情),我能够马上得到几个企业应用程序。

    它还使用相同的异径管工具运行。这是一篇很好的文章,涵盖了一些好处。

    因此,对于其他任何人来说,在搜索"Simpler Redux"之后,我建议尝试将其作为一个简单的替代方法,而不是使用所有的优点和1/4的样板文件。


    根据这篇文章:http:///a e medium.freecodecamp.org比较),前端框架,与一个基准更新4be0d3c78075 2019

    你更好的使用mobx设法在你的应用程序的数据得到更好的性能,需要的归来。