Typescript Redux/ImmutableJS嵌套状态+;不可变集合的Big-o复杂性

Typescript Redux/ImmutableJS嵌套状态+;不可变集合的Big-o复杂性,typescript,redux,immutability,ngrx,immutable-collections,Typescript,Redux,Immutability,Ngrx,Immutable Collections,我正试图为我的第一个Redux(NGRX/Store)项目了解不变性。事实证明,避免状态变异非常痛苦,在与Object.assign({})和状态变异错误进行斗争之后,我发现了Immutable.JS。这让事情变得容易多了 假设我有一个金融交易应用程序,它需要在加载时在图表上显示一组条形图。每秒有几次,最后一个酒吧需要根据实时价格信息进行更新,每隔一段时间就会添加一个新酒吧 对于{1-n}金融工具(欧元/美元/英镑/日元/黄金/石油等),这一切都需要发生。因此,我为我的应用程序的这一部分提出了这

我正试图为我的第一个Redux(NGRX/Store)项目了解不变性。事实证明,避免状态变异非常痛苦,在与Object.assign({})和状态变异错误进行斗争之后,我发现了Immutable.JS。这让事情变得容易多了

假设我有一个金融交易应用程序,它需要在加载时在图表上显示一组条形图。每秒有几次,最后一个酒吧需要根据实时价格信息进行更新,每隔一段时间就会添加一个新酒吧

对于{1-n}金融工具(欧元/美元/英镑/日元/黄金/石油等),这一切都需要发生。因此,我为我的应用程序的这一部分提出了这个模型:

export interface CandleState {
  LastCompletedCandle : Candle;
  InProgressCandle : Candle;
  LastTick:Offer;
  ClosedCandles:immutable.List<Candle>;
};

export interface AllCandleState {
   instruments: immutable.Map<string, CandleState>
}
实际上是返回一个全新的状态,因此我不清楚是否需要这样的嵌套不变性。。。。我确实希望能够订阅ClosedHandles列表上的更改;使其不可变会让事物直接观察到变化吗?或者这些东西只是从“顶层”检测到的

我想我的下一个问题是:我需要担心这个吗。我已经意识到改变一个不可变的集合是一个非常昂贵的操作。如果我做list.push或map.set,设置引擎盖下实际发生的事情。每次我需要更改不可变集合中的某些内容时,我是否会将整个数组中的每一项或映射一个接一个地复制到一个全新的数组/映射中?还是我只是换了个参考资料什么的

我希望有一些关于不可变集合的巨大复杂性的公开信息,这将使人们很容易理解这些东西将如何执行,但我在任何地方都找不到

这样做“不变性中的不变性”有什么意义吗

在大多数情况下,最基本的答案是:否。-出于更改检测目的,对象是否不可变并不重要-但是它确实帮助您强制执行始终创建新对象的概念,并且从不在存储外部(甚至在reducer本身中)改变现有状态

我确实希望能够订阅ClosedHandles上的更改 列表使这一点不可改变会让事情持续观察下去吗 直接改变?或者这些东西只是从“顶部”检测到的 水平

是和否。通过设置一个直接选择
仪器的流,可以直接观察变化。ClosedHandles
-但是这不是不变性的特例,可以在有或没有不变性的情况下完成

现在谈谈不变性和自上而下的部分:情况总是这样,当您想要在对象的n个级别上更改某个内容时,必须重新创建已更改对象的每个父对象(直到根),因为如果不可变,则不能更改父对象,因此您不能只设置一个新引用

例如:

root                <-- to enable changing the map1, you have to recreate the root, since it is immutable
|--map1             <-- to enable changing the set2, you have to recreate this map, since it is immutable
|  |--set1          <-- untouched, the "new version" of map1 will reference the same "set1"
|  \--set2          <-- to enable changing the attribute2, you have to recreate this set, since it is also immutable
|     |--attribute1 <-- untouched, the "new version" of set2 will just have the same reference on this object as the "old version"
|     \--attribute2 <-- you want to alter this attribute
|
|--map2             <-- untouched, the "new version" of root will reference the same "map2"
\--map3             <-- untouched, the "new version" of root will reference the same "map3"
根目录
root                <-- to enable changing the map1, you have to recreate the root, since it is immutable
|--map1             <-- to enable changing the set2, you have to recreate this map, since it is immutable
|  |--set1          <-- untouched, the "new version" of map1 will reference the same "set1"
|  \--set2          <-- to enable changing the attribute2, you have to recreate this set, since it is also immutable
|     |--attribute1 <-- untouched, the "new version" of set2 will just have the same reference on this object as the "old version"
|     \--attribute2 <-- you want to alter this attribute
|
|--map2             <-- untouched, the "new version" of root will reference the same "map2"
\--map3             <-- untouched, the "new version" of root will reference the same "map3"