Skip to content

Clarify when/where to do transformations of state with select #225

Open
@e-schultz

Description

@e-schultz

Cleanup below into proper docs/include it in our documentation:

with @select, and also probably for ngrx/store.select - be mindful of doing transformations in your select statement, probably want to put it further down the observable stream.

class Something {
    @select((state)=>activeFilters(state.filters)) activeFilters$;

    ngOnInit() {
      this.filteredCats$ = this.cats$
      .combineLatest(this.activeFilters$,
      (cats, filters: any) => cats.filter(filters)
    );
    }
}
/*

Every time there is a state change, the `activeFilters` gets called - if this is a heavy operation, there could be a performance hit. So above `activeFilters` called pretty much for every state change, even if nothing gets changed in the filters

However, select the slice of state that you want, then transform it, like below - activeFilters only gets called 
if the filters$ emits a new value.

If activeFilters was a heavy operation - there could be a performance hit. 
*/

class Something {
    @select() filters$;
    @select() cats$
    ngOnInit() {
      this.filteredCats$ = this.cats$
     .combineLatest(this.filters$.map(activeFilters),
     (cats, filters: any) => cats.filter(filters));
    }
}

I’ve seen some code that does heavy lifting in .select/@select (and think even the ng2-redux docs have examples of that) - maybe if using reselect that is memorizing that stuff - might not be so bad

basically the difference of ‘transform whenever any part of the state changes’, vs ‘transform when the part of the state I care about changes’ - which then impacts how other components are handling change detection, because when doing in it in select -> you will be getting a new object out every time, even if nothing changes - potentially triggering unnecessary change detection.

@SethDavenport from slack - yeah ideally you want it after the distinctUntilChanged that both libs do as part of the select

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions