Redux不仅仅是美化全球状态吗?

Rya*_*hel 75 javascript state immutability reactjs redux

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

国家通常被认为是非常邪恶的,并且是编程中的大量漏洞.而不是在整个应用程序中散布它全部Redux说为什么不把它全部集中在一个全局状态树中,你必须发出改变的动作?听起来不错.所有程序都需要状态,所以让我们把它放在一个不纯净的空间中,只在那里修改它,这样就很容易找到错误.然后我们也可以声明性地将各个状态片段绑定到React组件并让它们自动重绘,一切都很美.

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

case COMPLETE_TODO:
  return [
    ...state.slice(0, action.index),
    Object.assign({}, state[action.index], {
      completed: true
    }),
    ...state.slice(action.index + 1)
  ];
Run Code Online (Sandbox Code Playgroud)

而不是这个:

case COMPLETE_TODO:
  state[action.index].completed = true;
Run Code Online (Sandbox Code Playgroud)

更不用说我正在制作一个在线白板只是为了学习,每个状态的变化可能就像在命令列表中添加画笔笔划一样简单.经过一段时间(数百次刷子)复制整个阵列可能会开始变得非常昂贵和耗时.

我没有使用独立于通过操作进行变异的UI的全局状态树,但它确实需要是不可变的吗?像这样的简单实现有什么问题(非常粗略的草案.在1分钟内写完)?

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;
}
Run Code Online (Sandbox Code Playgroud)

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

lor*_*non 46

Redux不仅仅是美化全球状态吗?

当然如此.但是对于您曾经使用的每个数据库都是如此.最好将Redux视为内存数据库 - 您的组件可以反应性地依赖它.

Immutability可以检查是否有任何子树被更改非常有效,因为它简化了身份检查.

是的,您的实现很有效,但每次以某种方式操作树时,都必须重新渲染整个虚拟dom.

如果您正在使用React,它最终会对实际的dom执行diff并执行最小的批量优化操作,但完全自上而下的重新渲染仍然是低效的.

对于不可变树,无状态组件只需要检查它所依赖的子树是否与先前值相比在身份上有所不同,如果是,则可以完全避免渲染.

  • Reacts Virtual DOM也不是什么神奇的东西 - 从React docs引用:"生成将一棵树转换成另一棵树的最小操作次数是一个复杂且研究得很好的问题 - 最先进的算法在顺序上有复杂性of O(n3)其中n是树中节点的数量." (4认同)
  • 这不是一个不成熟的优化吗?另外,我们如何知道不断复制不可变对象的成本低于重新呈现DOM的成本(React的Virtual DOM也不会大幅降低此成本?) (3认同)
  • 那么,GUI库这种优化很长一段时间(参见:http://bitquabit.com/post/the-more-things-change/)对不可变数据结构的额外管理并不像你想象的那么昂贵 - 例如,如果一个节点发生变化,只有一个父节点链需要链 - 其余的节点不受影响.因此,我们不会为每个操作复制*whole*数据结构 - 我们重用未更改的子组件来构建新的数据结构. (3认同)
  • 在实践中React能够表现得更好的原因是:React依赖于启发式算法-因此:“如果您不提供稳定的键(例如,使用Math.random()),则所有子树都将每次都可以重新渲染。通过给用户选择密钥的选择,他们可以自行射击。” 因此,就像您可以通过提供稳定的键来帮助React一样,您也可以通过提供不可变的数据道具来帮助React。 (2认同)