Han Che
Han Che

Reputation: 8519

redux and ngrx - avoid unnecessary value firing through changes in the same reducer

This is a general ngrx / rxjs question i guess. I have three data-arrays:

currently I have them all in a single reducer called data.

const INITIAL_STATE: State = {
    projects: [],
    todos: [],
    events: []
};

I subscribe to the properties through a custom Selector with

export const getProjects = createSelector(getDataState, fromData.getProjects);
export const getTodos = createSelector(getDataState, fromData.getTodos);

So in a component I have

store.select(fromRoot.getProjects).subscribe()

If I understood it correctly, this will fire each time the value of projects if there was ANY change in the entire reducer.

So there could have been 10 changes to the todos and projects will still fire 10 times the same value, potentially triggering functions within the subscribe unnecessarily 10 times.

Other than creating a separate reducer for each property, are there other ways to avoid that?

Upvotes: 2

Views: 1515

Answers (2)

Fan Cheung
Fan Cheung

Reputation: 11380

One way to do that is to split them into different reducer Another approach will be create a custom selector like something below

this.foo=store.select('somereducer').pluck('yourtargetobject').distinctUntilChanged()

if you need to compare value in object to distinguish whether object's changed, you can use comparer

/* With comparer */
var source = Rx.Observable.of({value: 42}, {value: 42}, {value: 24}, 
{value: 24})
  .distinctUntilChanged(function (x) { return x.value; }, function 
(a,b) { return a !== b; });

Upvotes: 1

tlt
tlt

Reputation: 15281

have you tested it? because, answer is no, this will fire only when the change happen on getProjects slice of the state.

additionally, you might want to split your components into smart/dumb ones and bind data to dumb components using async pipe. that way you don't subscribe to store at all since async pipe does that for you.

then in your smart component you just write:

this.propertyX$ = this.store(yourReducer.yourReducerStateProperty);

and in your smart components html you bind to your dumb component:

<dumb-component [propertyX]=propertyX$ | async> </dumb-component>

Upvotes: 2

Related Questions