【发布时间】:2016-06-30 18:12:54
【问题描述】:
我在我的应用程序中使用了 React + Redux + Reselect + Immutable.js 的终极组合。我喜欢重新选择的想法,因为它让我的状态(由减速器维护)尽可能简单。我使用选择器来计算我需要的实际状态,然后将其提供给 React 组件。
这里的问题是,reducers 中的一个小变化会导致选择器重新计算整个派生输出,结果整个 React UI 也被更新。 我的纯组件没有工作。很慢。
典型示例:我的数据的第一部分来自服务器,基本上是不可变的。第二部分由客户端维护,并使用 redux 操作进行变异。它们由单独的 reducer 维护。
我使用选择器将这两个部分合并为一个记录列表,然后将其传递给 React 组件。但很明显,当我更改其中一个对象中的单个内容时,会重新生成整个列表并创建 Records 的新实例。并且 UI 完全重新渲染。
显然,每次都运行选择器效率不高,但仍然相当快,我愿意做出权衡(因为它确实使代码更简单、更清晰)。问题是实际渲染速度很慢。
我需要做的是将新选择器输出与旧选择器深度合并,因为 Immutable.js 库足够聪明,不会在没有任何更改时创建新实例。但由于选择器是无法访问先前输出的简单函数,我想这是不可能的。
我认为我目前的方法是错误的,我想听听其他想法。
在这种情况下,可能要走的路是摆脱重新选择,并将逻辑移动到使用增量更新来维护所需状态的减速器层次结构中。
【问题讨论】:
-
您确定为列表中的每个项目正确分配了唯一的关键道具吗? React 应该优化渲染(参见facebook.github.io/react/docs/multiple-components.html)。
-
不,这里的问题是选择器会生成一组全新的记录(这意味着新实例),无论它们是否更改。这就是为什么它总是被重新渲染。
-
即便如此,您说性能消耗不会发生在选择器中,而是在渲染时。我认为 react diffing 算法在提供唯一密钥时应该避免不必要的重新渲染(参见facebook.github.io/react/docs/reconciliation.html)。不确定差异算法是否适用于参考更改。
-
我认为我们讨论的是不同的问题。您正在链接处理生成的 React 树和实际 DOM 树之间协调的 diff 算法。我正在处理的是当前状态(假设传递给组件的道具)和 React 树之间的协调。我试图实现 React 树不会首先改变,除非状态发生实际变化。 React 的 diff 算法很快但不够快,有时这对于获得可用性能是必要的。见facebook.github.io/react/docs/pure-render-mixin.html
标签: reactjs redux immutable.js reselect