Reputation: 1618
We are using ngrx / store in our Angular 2 app. Our store is combined of Reducers "cameraReducer", "subjectReducer"
... and we want to maintain a few global and also common (across diff functionalities) items like "Loading Data" properties in "appReducer"
.
In a scenario like this, does it make sense to share an action like {type:LOADING_*, payload}
between individualReducers
and appReducer
? This should be turned on while a functionality (which can be thought of like one singular piece of data operation [using a single Reducer and a single action] or multiple related data operations [using multiple reducers and multiple actions]) is started and turned off once completed. The appReducer can look like this:
case LOADING_CAMERA:
LOADING_SUBJECT:
return state.setIn('loading') = true;
Adv - No Boilerplate. Cons - Ordering of reducers will play a role as to when the indicator pops on/off.
Or
case LOADING:
return state.setIn('loading') = true;
we can have code like at the beginning / end of the invoking each functionality
this.store.dispatch({action:'LOADING', payload: true});
//functionality
this.store.dispatch({action:'LOADING', payload: false});
Adv - Controlled Ordering of Indicator pop on/off. Cons - Boilerplate code to turn on/off loading.
Or
We can try to compute the "loading" as a combined observables (with each reducer having their own local "loading" property and an Observable of that property).
Adv - No Boilerplate and Controlled Ordering on indicator on/off. Cons - Increased complexity and more code may be.
Upvotes: 1
Views: 1236
Reputation: 1825
There is also the option of using Effects. You can subscribe to changes in StateUpdates which triggers whenever there is a state change. I find the example app at https://github.com/ngrx/example-app to be a great source of information on how to structure the app and ngrx.
For example,
@Effect() loadCollection$ = this.updates$
.whenAction(BookActions.LOAD_COLLECTION)
.switchMapTo(this.db.query('books').toArray())
.map((books: Book[]) => this.bookActions.loadCollectionSuccess(books));
When the LOAD_COLLECTION is dispatched, this is called which does the background work and dispatches the LOAD_COLLECTION_SUCCESS which updates the component. It seems that any impure function that has side effects work best this way, leaving only pure functions in the reducers.
Upvotes: 0
Reputation: 67449
The typical approach to organizing a Redux store is to structure your data by some kind of domain per key, and to define a reducer function that is given delegated responsibility for maintaining updates to that slice of state, usually composed with the combineReducers
utility. Redux absolutely encourages you to have multiple sub-reducer functions responding to the same incoming actions, so that sliceA
and sliceB
are independently updated as appropriate. Ordering should not be a concern, as each sub-reducer is generally unaware of any other parts of the state, and only concerned with updating its own slice. See this answer in the Redux FAQ for some related info: http://redux.js.org/docs/FAQ.html#reducers-share-state .
Upvotes: 2