【问题标题】:NgRx selector emits when anything on the state changes/memoization of selector not workingNgRx 选择器在状态发生任何变化/选择器的记忆不起作用时发出
【发布时间】:2019-07-18 12:28:12
【问题描述】:

我正在使用 Angular 7 和 NgRx。我创建了一个选择器来使用filter 从存储中获取一些数据,但是当存储中的任何内容发生更改时,此选择器会发出,即使它与我的选择器无关。

我已经创建了我的问题的演示。这是我的选择器:

export const getMyArrayFilter = createSelector(
    getCounterState,
    state => state.myArray.filter(x => x === 'new Item')
);

我在这里使用我的getMyArrayFilter 选择器:

this.store.pipe(select(fromRoot.getMyArrayFilter)).subscribe(x => console.log(x));

但如前所述,此selector 将在状态发生任何变化时发出。

请查看this StackBlitz 演示。

如果您尝试单击“将项目添加到数组”或“-”或“+”按钮,那么我的 getMyArrayFilter 将发出,并每次登录到控制台。我的选择器不应该只在我的状态发生变化时发出myArray 的值吗?

我查看了this SOF 问题,其中提到使用distinctUntilChanged,但这似乎对我不起作用。

【问题讨论】:

  • 正常的选择器会在 store 发生变化时发出新的值。我不明白你的问题是什么
  • @TonyNgo 我的选择器不应该只在myArray 我的状态发生变化时才发出值吗?
  • 选择器会在有任何变化时发出值。在您的代码中,您调用了 3 次 fromRoot.getCount(),因此它将返回 3 次数据

标签: javascript angular rxjs ngrx


【解决方案1】:

用你的例子做一些测试我只是注意到ngrx通过引用而不是其中的每个项目来比较数组,这意味着由于函数过滤器返回一个带有新引用的新数组,ngrx认为这是不同的这就是每次发生变化时都会调用订阅的原因。

创建一个新副本将具有相同的效果:


export const getMyArrayFilter = createSelector(
    getCounterState,
    state => [ ...state.myArray ]
);

【讨论】:

    【解决方案2】:

    正如 Alejandro 所指出的,这是因为 myArray 有一个新的引用。 您可以根据自己的需要修改记忆,Alex Okrushko 在他的演讲中就是这样做的 NgRx: Selectors are more powerful than you think

    【讨论】:

      猜你喜欢
      • 2019-05-16
      • 1970-01-01
      • 2022-07-18
      • 2016-01-23
      • 2016-01-23
      • 1970-01-01
      • 2019-03-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多