我刚刚发现了Redux。一切看起来都不错。使用Redux over Flux是否有任何缺点,陷阱或妥协?谢谢
Redux的作者在这里!
我想说你将使用它做出以下妥协:
我认为第一个是初学者的最大障碍,第二个可能是过度热情的早期采用者的问题,第三个是我个人的宠儿。除此之外,我不认为使用Redux会带来Flux避免的任何特殊缺点,有些人说它与Flux相比甚至有一些上升空间。
另见我对upsides of using Redux的回答。
Redux和Flux都需要大量的样板代码来涵盖许多常见模式,尤其是那些涉及异步数据获取的模式。 Redux文档已经有一些减少样板的例子:http://redux.js.org/docs/recipes/ReducingBoilerplate.html。您可以从像Alt或Fluxxor这样的Flux库中获得所需的一切,但Redux更喜欢自由而不是功能。对于一些开发人员而言,这可能是一个缺点,因为Redux会对您的状态做出某些可能无意中被忽视的假设。
您真正回答问题的唯一方法是尝试使用Redux,如果可以的话,也许是在个人项目中。 Redux的出现是因为需要更好的开发人员体验,并且它偏向于函数式编程。如果您不熟悉减速器和功能组合等功能概念,那么您可能会放慢速度,但只会略微降低。在数据流中采用这些想法的好处是更容易测试和可预测性。
免责声明:我从Flummox(一种流行的Flux实现)迁移到Redux,其优势远远超过任何缺点。在我的代码中,我更喜欢魔法。更少的魔力来自于更多的样板,但这是一个非常小的代价。
使用Redux而不是其他Flux替代品的最大好处之一是它能够将您的思维重新定向为更具功能性的方法。一旦你理解了电线如何连接你就会发现它的优雅和简约的设计,并且永远不会回头。
Redux不是纯粹的Flux实现,但绝对受到Flux的启发。最大的区别在于它使用单个存储来包装包含应用程序所有状态的状态对象。您不会像在Flux中那样创建商店,而是编写可以改变单个对象状态的reducer函数。此对象表示应用中的所有状态。在Redux中,您将获得当前操作和状态,并返回新状态。这意味着动作是顺序的,状态是不可变的。这让我想到了Redux中最明显的骗局(在我看来)。
原因很少: 1.连贯性 - 存储器的状态总是被减速器改变,因此很容易跟踪谁改变了什么。 2.性能 - 因为它是不可变的,Redux只需要检查以前的状态!==当前状态以及是否要呈现。无需每次都将状态循环到确定的渲染。 3.调试 - 像Time Travel Debugging和Hot Reloading这样令人敬畏的新概念。
更新:如果这不足以说服,请观看Lee Byron关于Immutable User Interfaces的优秀演讲。
Redux需要通过代码库/库的开发人员纪律来维护这个想法。您需要确保选择库并以不可变的方式编写代码。
如果您想了解更多关于Flux概念的不同实现(以及最适合您需求的概念),请查看this有用的比较。
在说完之后,我必须承认Redux是JS未来发展的目标(就像写这些行一样)。
我更喜欢使用Redux,因为它使用一个商店,与Flux相比,状态管理更容易,Redux DevTools它是非常有用的工具,可以让你通过一些有用的数据看看你在你的状态下做了什么,它真的与React开发工具一致。
Redux也可以与Angular等其他流行框架一起使用。无论如何,让我们看看Redux如何将自己介绍为一个框架。
Redux有三个原则可以很好地引入Redux,它们也是Redux和Flux之间的主要区别。
唯一的事实来源
整个应用程序的状态存储在单个存储中的对象树中。
这样可以轻松创建通用应用程序,因为服务器中的状态可以序列化并融入客户端,无需额外的编码工作。单个状态树还可以更轻松地调试或检查应用程序;它还使您能够在开发过程中保持应用程序的状态,从而加快开发周期。传统上难以实现的一些功能 - 例如Undo / Redo - 如果您的所有状态都存储在一个树中,则可能会突然变得微不足道。
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
}
]
}
*/
State是只读的
改变状态的唯一方法是发出一个动作,一个描述发生的事情的对象。
这可以确保视图和网络回调都不会直接写入状态。相反,他们表达了改变国家的意图。因为所有的变化都是集中的,并且按照严格的顺序逐个发生,所以没有细微的竞争条件需要注意。由于操作只是普通对象,因此可以对其进行记录,序列化,存储以及稍后重放以进行调试或测试。
store.dispatch({
type: 'COMPLETE_TODO',
index: 1
})
store.dispatch({
type: 'SET_VISIBILITY_FILTER',
filter: 'SHOW_COMPLETED'
})
使用纯函数进行更改
要指定状态树如何通过操作转换,您可以编写纯缩减器。
Reducers只是纯函数,它采用先前的状态和动作,并返回下一个状态。记住返回新的状态对象,而不是改变以前的状态。您可以从单个reducer开始,随着应用程序的增长,将其拆分为更小的reducers,管理状态树的特定部分。因为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)
欲了解更多信息,请访问here
Redux需要有关不变性的纪律。我可以推荐的东西是ng-freeze,让你知道任何意外的状态变异。
据我所知,redux的灵感来自于助焊剂。 flux是一种类似MVC(模型视图控制器)的架构。 facebook在使用MVC时引入了由于可伸缩性问题引起的流量。所以flux不是一个实现,它只是一个概念。实际上,redux是通量的实现。