Answers:
Redux作者在这里!
我想说的是,您将在使用它时做出以下折衷:
您将需要学习避免突变。Flux对突变数据毫无疑问,但是Redux不喜欢突变,并且许多与Redux互补的软件包都假定您永远不会突变状态。您可以使用仅限开发人员的软件包(例如redux-immutable-state-invariant),使用Immutable.js或信任自己和您的团队编写非可变代码来实施此操作,但这是您需要了解的,并且需要是您的团队接受的有意识的决定。
您将需要仔细挑选包裹。尽管Flux明确不尝试解决“附近”的问题,例如撤消/重做,持久性或形式,但是Redux具有扩展点,例如中间件和商店增强器,它催生了一个年轻而丰富的生态系统。这意味着大多数软件包都是新主意,尚未达到临界使用量。您可能依赖于几个月后显然不是一个好主意的东西,但是目前还很难说。
您将没有很好的Flow集成。 Flux当前使您可以做非常令人印象深刻的静态类型检查,Redux 尚不支持。我们会到达那里,但需要一些时间。
我认为第一个是初学者最大的障碍,第二个可能是对热情过度的早期采用者的困扰,第三个是我个人的宠儿。除此之外,我认为使用Redux不会给Flux带来任何特殊的不利影响,有人说与Flux相比它甚至还有一些缺点。
另请参阅我关于使用Redux的好处的答案。
shallowEqual
检查中用于确定状态是否已更改。但可以将其替换为deepEqual或JSON.stringify并进行比较。最终,它的性能会有所降低-但它是纯计算而不涉及DOM-足够快。并且在任何情况下渲染本身都是相同的
Redux和Flux都需要大量的样板代码来覆盖许多常见的模式,尤其是那些涉及异步数据获取的模式。Redux文档中已经有一些减少样板的示例:http : //redux.js.org/docs/recipes/ReducingBoilerplate.html。您可以从Alt或Fluxxor等Flux库中获得所需的一切,但是Redux宁愿自由而不是功能。对于某些开发人员而言,这可能是不利的一面,因为Redux对您的状态做出了某些假设,而这些假设可能会无意间被忽略。
真正回答问题的唯一方法是,如果可以的话,可以尝试在个人项目中尝试Redux。Redux之所以出现是因为需要更好的开发人员体验,并且偏向于函数式编程。如果您不熟悉诸如reducers和function composition之类的功能概念,那么您可能会放慢速度,但会稍微放慢速度。将这些思想包含在数据流中的好处是更容易测试和可预测。
免责声明:我从Flummox(一种流行的Flux实现)迁移到Redux,其优点远大于缺点。我更喜欢代码中的魔术。更少的魔术花费了更多的样板,但付出的代价却很小。
Redux并不是纯粹的Flux实现,而是绝对受Flux启发的。最大的区别在于,它使用单个存储来包装包含您应用程序所有状态的状态对象。与其像在Flux中那样创建存储,不如编写将更改单个对象状态的reducer函数。该对象代表您应用中的所有状态。在Redux中,您将获得当前操作和状态,并返回新状态。这意味着动作是顺序的,状态是不可变的。这使我进入了Redux最明显的缺点(我认为)。
造成这种情况的原因很少:
1. 一致性 -减速器总是在更改商店的状态,因此可以轻松跟踪谁进行了更改。
2. 性能 -因为它是不可变的,所以Redux只需要检查以前的状态是否=!==当前状态以及是否可以渲染。无需每次都将状态循环到确定的渲染。
3. 调试 -很棒的新概念,例如Time Travel Debugging和Hot Reloading。
更新:如果这还没有足够的说服力,请观看Lee Byron关于不可变用户界面的精彩演讲。
Redux要求开发人员通过代码库/库来保持这一想法。您需要确保选择库并以不可更改的方式编写代码。
如果您想了解有关Flux概念的不同实现的更多信息(以及最适合您的需求的信息),请查看此有用的比较。
说完这些之后,我必须承认Redux是JS未来开发的目标(就像写这些行一样)。
我更喜欢使用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)
欲了解更多信息,请访问这里
据我所知,redux是受通量启发的。Flux是类似于MVC(模型视图控制器)的体系结构。由于使用MVC时,由于可伸缩性问题,facebook引入了变化。因此,flux不是实现,它只是一个概念。实际上,redux是通量的实现。