使用Redux而不是Flux会有什么弊端[关闭]


Answers:


411

Redux作者在这里!

我想说的是,您将在使用它时做出以下折衷:

  • 您将需要学习避免突变。Flux对突变数据毫无疑问,但是Redux不喜欢突变,并且许多与Redux互补的软件包都假定您永远不会突变状态。您可以使用仅限开发人员的软件包(例如redux-immutable-state-invariant),使用Immutable.js或信任自己和您的团队编写非可变代码来实施此操作,但这是您需要了解的,并且需要是您的团队接受的有意识的决定。

  • 您将需要仔细挑选包裹。尽管Flux明确不尝试解决“附近”的问题,例如撤消/重做持久性形式,但是Redux具有扩展点,例如中间件和商店增强器,它催生了一个年轻而丰富的生态系统。这意味着大多数软件包都是新主意,尚未达到临界使用量。您可能依赖于几个月后显然不是一个好主意的东西,但是目前还很难说。

  • 您将没有很好的Flow集成。 Flux当前使您可以做非常令人印象深刻的静态类型检查,Redux 尚不支持。我们会到达那里,但需要一些时间。

我认为第一个是初学者最大的障碍,第二个可能是对热情过度的早期采用者的困扰,第三个是我个人的宠儿。除此之外,我认为使用Redux不会给Flux带来任何特殊的不利影响,有人说与Flux相比它甚至还有一些缺点。


另请参阅我关于使用Redux的好处的答案。


1
很棒的答案。是否有简单的解释说明为什么在redux和补充软件包中可以避免突变?
rambossa

7
简而言之,通过变异,很难检查状态的哪些部分已更改,从而仅有效地重绘UI的已更改部分。它们也使调试更加困难,并且像github.com/omnidan/redux-undo之类的不可能了。最后,如果状态发生突变,则无法进行github.com/gaearon/redux-devtools中的时间旅行。
Dan Abramov

@DanAbramov不变性如何在Redux中帮助有效重绘?例如,在react-redux shallowEqual检查中用于确定状态是否已更改。但可以将其替换为deepEqual或JSON.stringify并进行比较。最终,它的性能会有所降低-但它是纯计算而不涉及DOM-足够快。并且在任何情况下渲染本身都是相同的
amakhrov 2015年

@amakhrov deepEqual或JSON.stringify相当慢。对于真正的应用程序,它们还不够“快”,尤其是当您比较每个视图的数据时。
丹·阿布拉莫夫

好,我知道了。听起来不可改变性使脏支票更有效,而不是使重绘更有效。
amakhrov 2015年

37

Redux和Flux都需要大量的样板代码来覆盖许多常见的模式,尤其是那些涉及异步数据获取的模式。Redux文档中已经有一些减少样板的示例:http : //redux.js.org/docs/recipes/ReducingBoilerplate.html。您可以从Alt或Fluxxor等Flux库中获得所需的一切,但是Redux宁愿自由而不是功能。对于某些开发人员而言,这可能是不利的一面,因为Redux对您的状态做出了某些假设,而这些假设可能会无意间被忽略。

真正回答问题的唯一方法是,如果可以的话,可以尝试在个人项目中尝试Redux。Redux之所以出现是因为需要更好的开发人员体验,并且偏向于函数式编程。如果您不熟悉诸如reducers和function composition之类的功能概念,那么您可能会放慢速度,但会稍微放慢速度。将这些思想包含在数据流中的好处是更容易测试和可预测。

免责声明:我从Flummox(一种流行的Flux实现)迁移到Redux,其优点远大于缺点。我更喜欢代码中的魔术。更少的魔术花费了更多的样板,但付出的代价却很小。


16

助焊剂Redux。。。

Redux并不是纯粹的Flux实现,而是绝对受Flux启发的。最大的区别在于,它使用单个存储来包装包含您应用程序所有状态的状态对象。与其像在Flux中那样创建存储,不如编写将更改单个对象状态的reducer函数。该对象代表您应用中的所有状态。在Redux中,您将获得当前操作和状态,并返回新状态。这意味着动作是顺序的,状态是不可变的。这使我进入了Redux最明显的缺点(我认为)。


Redux支持一个不变的概念。

为什么不变性?

造成这种情况的原因很少:
1. 一致性 -减速器总是在更改商店的状态,因此可以轻松跟踪谁进行了更改。
2. 性能 -因为它是不可变的,所以Redux只需要检查以前的状态是否=!==当前状态以及是否可以渲染。无需每次都将状态循环到确定的渲染。
3. 调试 -很棒的新概念,例如Time Travel DebuggingHot Reloading

更新:如果这还没有足够的说服力,请观看Lee Byron关于不可变用户界面的精彩演讲。

Redux要求开发人员通过代码库/库来保持这一想法。您需要确保选择库并以不可更改的方式编写代码。

如果您想了解有关Flux概念的不同实现的更多信息(以及最适合您的需求的信息),请查看有用的比较。

说完这些之后,我必须承认Redux是JS未来开发的目标(就像写这些行一样)。


15

与其他Flux替代品相比,使用Redux的最大好处之一就是它能够将您的思维重新定向为更实用的方法。一旦了解了所有电线的连接方式,您就会意识到其惊人的优雅和简洁的设计,再也回不去了。


4

我更喜欢使用Redux,因为它使用一个存储与Flux相比使状态管理容易得多,而且Redux DevTools它是非常有用的工具,它使您可以使用一些有用的数据查看对状态的处理方式,并且它确实与React开发工具保持一致。

此外,Redux在与其他流行的框架(例如Angular)一起使用时也具有更大的灵活性。无论如何,让我们看看Redux如何将自己介绍为框架。

Redux具有三个原理,可以很好地介绍Redux,它们也是Redux和Flux之间的主要区别。

真理的单一来源

整个应用程序的状态存储在单个存储中的对象树中。

这使得创建通用应用程序变得容易,因为您可以将服务器的状态序列化并合并到客户端中,而无需额外的编码工作。单个状态树还使调试或检查应用程序变得更加容易。它还使您能够保持应用程序的开发状态,从而缩短开发周期。如果您的所有状态都存储在单个树中,则某些传统上难以实现的功能(例如,撤消/重做)可能突然变得微不足道。

console.log(store.getState())

/* Prints
{
  visibilityFilter: 'SHOW_ALL',
  todos: [
    {
      text: 'Consider using Redux',
      completed: true,
    },
    {
      text: 'Keep all state in a single tree',
      completed: false
    }
  ]
}
*/

状态为只读

更改状态的唯一方法是发出一个动作,一个描述发生情况的对象。

这样可以确保视图和网络回调都不会直接写入状态。相反,他们表达了改变国家的意图。因为所有更改都是集中的,并且严格按照顺序进行,所以没有任何微妙的竞争条件值得关注。由于动作只是简单的对象,因此可以将它们记录,序列化,存储并在以后重播以进行调试或测试。

store.dispatch({
  type: 'COMPLETE_TODO',
  index: 1
})

store.dispatch({
  type: 'SET_VISIBILITY_FILTER',
  filter: 'SHOW_COMPLETED'
})

使用纯函数进行更改

要指定动作如何转换状态树,您可以编写纯约简。

Reducer只是纯函数,它们采用上一个状态和一个动作,然后返回下一个状态。记住要返回新的状态对象,而不是改变先前的状态。您可以从单个化简器开始,随着应用程序的增长,将其拆分为较小的化简器,用于管理状态树的特定部分。因为reducer只是函数,所以您可以控制它们的调用顺序,传递其他数据,甚至可以使可重复使用的reducer用于诸如分页之类的常见任务。

function visibilityFilter(state = 'SHOW_ALL', action) {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter
    default:
      return state
  }
}

function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case 'COMPLETE_TODO':
      return state.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: true
          })
        }
        return todo
      })
    default:
      return state
  }
}

import { combineReducers, createStore } from 'redux'
let reducer = combineReducers({ visibilityFilter, todos })
let store = createStore(reducer)

欲了解更多信息,请访问这里


0

Redux要求纪律性不变。我可以推荐的是ng-freeze,让您知道任何意外的状态突变。


-1

据我所知,redux是受通量启发的。Flux是类似于MVC(模型视图控制器)的体系结构。由于使用MVC时,由于可伸缩性问题,facebook引入了变化。因此,flux不是实现,它只是一个概念。实际上,redux是通量的实现。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.