Hi I am using Ngrx as the state management for my frontend project. Recently I found all the subscriptions are triggered when one field in the state is updated.
Suppose I have a state with field A and B. Correspondingly, I have AComponent and BComponent subscribing the value of A and B. Now if I keep dispatching an action to update A. the subscription of B will also be triggered all the time even though the value of B is not updated.
At the moment, what I am doing is in the subscription function of B, I check whether or not the value is changed, such as
if (this.B !== B) {
//do something
}
Is there any way that if I dispatch an action to update A, the subscription of B is not triggered? Or this is the a fundamental mechanism of NGRX?
Thank you
Update
Here is the selector I am using
this._store
.select("appState")
.pipe<T>(pluck("B"))
.subscribe(callback);
Update 2
According to @Anarno's answer, I added the selector as follow
const BFeatureSelector = createFeatureSelector<string>('b');
export const BSelector = createSelector(
BFeatureSelector,
state => state
);
At the meanwhile, I print a message in reducer to make sure B is updated as
case app.ActionType.B: {
console.info("b is update in reducter");
return Object.assign({}, state, { b: action.payload });
}
And then I use this BSelector in BComponent in the following three methods
this._store.select(BSelector).subscribe(b=> {
console.info("b is updated 1");
console.info(b);
});
this._store
.pipe(
map(state => BSelector(state))
)
.subscribe(b=> {
console.info("b is updated 2");
console.info(b);
});
this._store
.pipe(select(notificationSelector))
.subscribe(b=> {
console.info("b is updated 3");
console.info(b);
});
What I observe is both b is updated 1
and b is updated 3
only printed once when the component is initialised while b is updated 2
is printed all the time when other fields in state is updated. However, none of console.info(b);
in each method works. All three methods do not print the content of b.
You need a selector file, and make selectors like this:
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { BState } from '../../../reducers/index';
const selectBState = createFeatureSelector<BState>('BState');
export const selectBvalue = createSelector(
selectBState,
state => state.value
);