NgRx selector emits when anything on the state changes/memoization of selector not working

孤者浪人 提交于 2019-12-13 01:18:02

问题


I'm using Angular 7 along with NgRx. I have created a selector to get some data from the store using filter, but this selector emits when anything on the store changes, even if it is not related to my selector.

I have created a demonstration of my issue. Here is my selector:

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

And here I am using my getMyArrayFilter selector:

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

But as mentioned, this selector will emit anytime anything changes on the state.

Please take a look at this StackBlitz demonstration.

If you try clicking on either the "Add item to array" or "-" or "+" buttons, then my getMyArrayFilter will emit, and log to the console each time. Should't my selector only emit values IF the myArray on my state changes?

I have taken a look at this SOF question which mentions using distinctUntilChanged but that doesn't seem to work for me.


回答1:


As Alejandro pointed out, this is because there's a new reference for myArray. You can modify the memoization to your needs, Alex Okrushko does exactly this in his talk NgRx: Selectors are more powerful than you think




回答2:


Doing some testing with your example I just notice that ngrx compare the arrays by reference and not by every item inside of it, what this means is that since the function filter return a new array with a new reference ngrx thinks that is different and that is why the subscribe is called every time something changes.

Creating a new copy will have the same effect:


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


来源:https://stackoverflow.com/questions/57094478/ngrx-selector-emits-when-anything-on-the-state-changes-memoization-of-selector-n

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!