After tracking down unexpected requests being made I've found that my app's global user
state's slices emit upon every navigation.
What are potential causes of an NGXS state slice
- emitting where its data hasn't changed and
- actions have not been dispatched
Here is the chronological order of events in the app
- OnInit
- slice emits -> fetch with params <-- EXPECTED
- user clicks to navigate to a new page
- UserState selectors emit -> fetch with params <-- UNEXPECTED
- OnDestroy
Obviously we don't want slices to emit for no changes in data.
#4 demonstrates a side-effect where an unnecessary request is triggered.
Here is the code
@Selector()
public static scope(state: DataModel) {
console.log('scope triggered');
return state.scope;
}
// Actions only trigger once as expected
@Action(GetScopes)
getAvailableScopes(ctx: StateContext<DataModel>) {
return this.apiService.get('/scopes').pipe(
tap((result) => {
ctx.setState(
patch<DataModel>({
scope: result.scopes,
})
);
})
);
}
The app is not complex but I cannot replicate unexpected slices emitting in StackBlitz Github issue
It should be noted that the state does not change!
ngxsOnChanges(change: NgxsSimpleChange) { ...
only fires when the app inits and is never again triggered within in this flow despite the state's selectors emitting on navigation.