使用 Redux 而不是 Flux 的缺点是什么

What could be the downsides of using Redux instead of Flux

我最近才发现 Redux。一切看起来都不错。使用 Redux 而不是 Flux 有什么缺点、问题或妥协吗?谢谢

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

真正回答你的问题的唯一方法是如果可以的话尝试 Redux,也许在个人项目中。 Redux 的出现是因为需要更好的开发者体验,它偏向于函数式编程。如果您不熟悉 reducer 和函数组合等函数式概念,那么您的速度可能会变慢,但速度会很慢。在数据流中采用这些想法的好处是更容易测试和可预测性。

免责声明:我从 Flummox(一种流行的 Flux 实现)迁移到 Redux,其优点远大于缺点。我更喜欢在我的代码中使用更少的魔法。更少的魔法是以更多的样板为代价的,但这是一个非常小的代价。

这里是 Redux 作者!

我想说您将在使用它时做出以下妥协:

  • 你需要学会避免突变。 Flux 对突变数据没有意见,但 Redux 不喜欢突变和许多与 Redux 互补的包假设你永远不会改变状态。您可以使用 redux-immutable-state-invariant, use Immutable.js 之类的仅限开发包来强制执行此操作,或者相信您自己和您的团队会编写非可变代码,但这是您需要注意的事情,并且这是您有意识地接受的决定团队.

  • 您将不得不仔细挑选您的包裹。 虽然 Flux 明确不会尝试解决“附近”问题,例如 undo/redo, persistence, or forms, Redux has extension points such as middleware and store enhancers, and it has spawned a young but rich ecosystem.这意味着大多数软件包都是新创意,尚未达到临界使用量。您可能依赖于几个月后显然不是一个好主意的东西,但现在还很难说。

  • 您还没有很好的 Flow 集成。 Flux currently lets you do very impressive static type checks which Redux doesn't support yet。我们会到达那里,但这需要一些时间。

我认为第一个是初学者的最大障碍,第二个可能是过度热情的尝鲜者的问题,第三个是我个人的烦恼。除此之外,我不认为使用 Redux 会带来 Flux 所避免的任何特定缺点,并且有人说与 Flux 相比它甚至有一些优点。


另见我在 上的回答。

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

Flux and Redux。 . .

Redux 不是纯粹的 Flux 实现,但绝对受到 Flux 的启发。最大的区别在于它使用单个存储来包装一个包含应用程序所有状态的状态对象。您无需像在 Flux 中那样创建存储,而是编写将更改单个对象状态的缩减器函数。该对象代表您应用中的所有状态。在 Redux 中,您将获得当前的操作和状态,以及 return 一个新状态。这意味着动作是连续的,状态是不可变的。这让我想到了 Redux 中最明显的缺点(在我看来)。


Redux 支持 immutable 概念。

为什么不可变?

有几个原因:
1. Coherence - store 的状态总是由 reducer 更改,因此很容易跟踪谁更改了什么。
2. Performance - 因为它是不可变的,Redux 只需要检查前一个状态是否 !== 当前状态,如果是就渲染。无需每次都循环状态来确定渲染。
3. 调试 - 新的很棒的概念,如 Time Travel Debugging and Hot Reloading.

更新:如果这还不够说服力,请观看 Lee Byron excellent talk about Immutable User Interfaces

Redux 需要开发人员通过 codebase/libraries 来维护这个想法。您需要确保选择库并以 non-mutable 方式编写代码。

如果您想详细了解 Flux 概念的不同实现方式(以及最适合您的需求的方式),请查看this 有用的比较。

说到这里,不得不承认Redux是JS未来发展的方向(至于写这几行)

Redux 需要关于不变性的纪律。我可以推荐的东西是 ng-freeze 让你知道任何意外的状态突变。

我更喜欢使用 Redux,因为它使用一个存储,这使得状态管理比 Flux 更容易Redux DevTools 它是非常有用的工具,可以让你看到你用一些有用的数据对你的状态做了什么,它真的与 React 开发工具内联。

此外,Redux 在与其他流行框架(如 Angular 一起使用时具有更大的灵活性。 不管怎样,让我们​​看看Redux是如何介绍自己作为一个框架的。

Redux有三大原则,可以很好的介绍Redux,也是Redux和Flux的主要区别。

单一事实来源

The state of your whole application is stored in an object tree within a single store.

This makes it easy to create universal apps, as the state from your server can be serialized and hydrated into the client with no extra coding effort. A single state tree also makes it easier to debug or inspect an application; it also enables you to persist your app's state in development, for a faster development cycle. Some functionality which has been traditionally difficult to implement - Undo/Redo, for example - can suddenly become trivial to implement, if all of your state is stored in a single tree.

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
    }
  ]
}
*/

状态为只读

The only way to change the state is to emit an action, an object describing what happened.

This ensures that neither the views nor the network callbacks will ever write directly to the state. Instead, they express an intent to transform the state. Because all changes are centralized and happen one by one in a strict order, there are no subtle race conditions to watch out for. As actions are just plain objects, they can be logged, serialized, stored, and later replayed for debugging or testing purposes.

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

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

使用纯函数进行更改

To specify how the state tree is transformed by actions, you write pure reducers.

Reducers are just pure functions that take the previous state and an action, and return the next state. Remember to return new state objects, instead of mutating the previous state. You can start with a single reducer, and as your app grows, split it off into smaller reducers that manage specific parts of the state tree. Because reducers are just functions, you can control the order in which they are called, pass additional data, or even make reusable reducers for common tasks such as pagination.

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)

有关详细信息,请访问 here

据我所知,redux 的灵感来自 flux。 flux 是一种类似于 MVC(模型视图控制器)的架构。 facebook 在使用 MVC 时引入了由于可伸缩性问题引起的通量。所以 flux 不是一个实现,它只是一个概念。其实redux就是flux的实现。