Javascript Isn';Redux刚刚美化了全球国家?

Javascript Isn';Redux刚刚美化了全球国家?,javascript,reactjs,state,immutability,redux,Javascript,Reactjs,State,Immutability,Redux,所以我在一周前开始学习React,我不可避免地遇到了状态问题,以及组件应该如何与应用程序的其余部分通信。我四处搜索,发现Redux似乎是这个月的特色。我通读了所有的文档,我认为这实际上是一个相当革命性的想法。以下是我的想法: 人们普遍认为状态是相当邪恶的,是编程中的一个很大的bug来源。Redux说,与其将其分散在整个应用程序中,不如将其全部集中在一个全局状态树中,这样您就必须发出更改操作?听起来很有趣。所有的程序都需要状态,所以让我们把它放在一个不纯净的空间里,只从里面修改它,这样bug就很容

所以我在一周前开始学习React,我不可避免地遇到了状态问题,以及组件应该如何与应用程序的其余部分通信。我四处搜索,发现Redux似乎是这个月的特色。我通读了所有的文档,我认为这实际上是一个相当革命性的想法。以下是我的想法:

人们普遍认为状态是相当邪恶的,是编程中的一个很大的bug来源。Redux说,与其将其分散在整个应用程序中,不如将其全部集中在一个全局状态树中,这样您就必须发出更改操作?听起来很有趣。所有的程序都需要状态,所以让我们把它放在一个不纯净的空间里,只从里面修改它,这样bug就很容易被追踪到。然后,我们还可以声明性地绑定各个状态块以反应组件,并让它们自动重画,一切都很美好


然而,我对整个设计有两个问题。首先,为什么状态树必须是不可变的?假设我不关心时间旅行调试、热重新加载,并且已经在我的应用程序中实现了撤销/重做。这样做似乎太麻烦了:

case COMPLETE_TODO:
  return [
    ...state.slice(0, action.index),
    Object.assign({}, state[action.index], {
      completed: true
    }),
    ...state.slice(action.index + 1)
  ];
与此相反:

case COMPLETE_TODO:
  state[action.index].completed = true;
更不用说我制作一个在线白板只是为了学习,每一个状态的改变都可能像在命令列表中添加画笔一样简单。经过一段时间(数百次笔划)复制整个阵列可能会变得非常昂贵和耗时

我同意全局状态树,它独立于通过操作变异的UI,但它真的需要是不可变的吗?像这样一个简单的实现(非常粗略的草稿,在1分钟内完成)有什么问题

它仍然是一个全局状态树,通过发出的动作进行变异,但非常简单有效

Redux不就是被美化的全球国家吗

当然是。但您使用过的每个数据库都是如此。最好将Redux视为内存中的数据库,组件可以对其进行反应性依赖

不变性使检查任何子树是否被更改变得非常有效,因为它简化了身份检查

是的,您的实现是高效的,但是每次以某种方式操纵树时,都必须重新呈现整个虚拟dom

如果使用React,它最终将与实际dom进行差异,并执行最小的批处理优化操作,但完全自顶向下的重新渲染仍然效率低下


对于不可变的树,无状态组件只需检查它所依赖的子树是否与以前的值在标识上有所不同,如果是,则可以完全避免呈现。

“首先,为什么状态树需要不可变?”——然后必须提供一种算法来确定数据是否已更改。对于任意的数据结构(如果它是可变的),实现它是不可能的。获取
immutablejs
并使用
返回state.setIn([action.index,'completed'],true)减少boilerplate.PS:
返回state.map(i=>i.index==action.index?{…i,completed:true}:i)这不是有点过早的优化吗?此外,我们如何知道不断复制不可变对象的成本比重新呈现DOM的成本要低(React的虚拟DOM也不会大大降低这一成本?)好吧,GUI库长期以来一直在进行这种优化(请参阅:)另外,不可变数据结构的管理成本并不像您想象的那样高——例如,如果某个节点发生更改,则只需要一条父链进行链接——其余节点不会受到影响。因此,我们不会为每个操作复制整个数据结构-我们重用未更改的子组件来构建新的数据结构。此外,React虚拟DOM的事情并不完全是黑魔法-引用React文档:“生成将一棵树转换为另一棵树的最小操作数是一个复杂且经过充分研究的问题-最先进的算法的复杂性为O(n3),其中n是树中的节点数。React能够在实践中表现得更好的原因是:React依赖于启发式——因此:“如果您不提供稳定的键(例如使用Math.random()),那么每次都会重新渲染所有的子树。通过给用户选择钥匙的选择权,他们有能力射中自己的脚。“就像你可以通过提供稳定的键来帮助反应一样,你也可以通过提供不可变的数据道具来帮助反应。关于你的笔画数组——请参考:引用文档:列表是有序索引的密集集合,很像JavaScript数组。列表实现了从末尾(推、弹出)和开头(取消移动、移位)高效添加和删除数据的功能。
var store = { items: [] };

export function getState() {
  return store;
}

export function addTodo(text) {
  store.items.push({ "text": text, "completed", false});
}

export function completeTodo(index) {
  store.items[index].completed = true;
}