当减速器更改切片时,Ngrx选择器不触发

时间:2018-10-31 18:15:09

标签: angular ngrx

我正在开发一个广泛使用Ngrx存储的angular 2应用程序。我的商店结构不错。我使用选择器来检索状态切片,通常所有选择器都会正确触发其关联的订阅。 Ngrx很棒。

可悲的是,今天我走进一个新问题,尝试在网上四处寻找解决方案,但没有成功。通过测试不同的语法,我终于找到了解决方法,但是我很好奇为什么会这样。

此选择器与我所有其他选择器完全相同:

export const getToolBars = (state: State): any => state.toolBars;
export const selectState: MemoizedSelector<object, State> = createFeatureSelector<State>('http');
export const selectToolBars: MemoizedSelector<object, any> = createSelector(selectState, getToolBars);

问题在于,当通过化简器更新数据时,选择器不会像应有的那样触发订阅。

我找到了解决此特定情况的方法。使用这个:

export const getToolBars = (state: State): any => { return { toolBars: state.toolBars }; };

代替:

export const getToolBars = (state: State): any => state.toolBars;

解决了这个问题,但我希望所有的吸气剂看起来都一样,所以我想知道为什么这个问题首先发生?

其他信息,state.toolBars是一个接口为

的对象
toolBars: { [name: string]: any };

任何提示或引用都可以。现在一切都“正常”,我只是在寻找提高技能的方法。非常感谢你!

编辑:

我进行了一次闪电战以说明问题。

https://stackblitz.com/edit/angular-selector-issue?file=src%2Fapp%2Froot-store%2Ftest-store%2Fselectors.ts

在这次堆叠闪电战中,我通过reducer将日志添加到控制台,以便在toolBars状态下添加内容。每两秒钟就会向该状态添加一个新条目。

在当前状态下,当reducer添加内容时不会触发订阅。

如果在selectors.ts中,我们注释了第6行,而注释了第7行,则其作用与我的应用程序相同。而且我想知道为什么普通语法不会...

1 个答案:

答案 0 :(得分:2)

您正在直接修改状态,这就是问题所在。

默认情况下会记住选择器,并检查参数是否在上次调用和当前调用之间更改。此检查是简单的参考检查(===)。因为您是直接修改状态,所以引用保持不变。

要解决此问题,您可以执行以下操作:

return {
        ...state,
        toolBars: {
          ...state.toolBars,
          [action.value]: action.subValue
        }
}