This document discusses using Redux for data flow in Angular applications. Redux is a pattern that uses a single state tree and pure reducer functions to update state in response to actions. It advocates for single sources of truth, immutable state, and changes through pure functions. The ng2-redux library allows integrating Redux with Angular by providing the store via dependency injection and dispatching actions. Components can select state slices and dispatch actions to update state.
9. About Me
• sparXys CEO and senior consultant
• Microsoft MVP in the last 8 years
• Pro Single Page Application Development (Apress) co-author
• 4 Microsoft Official Courses (MOCs) co-author
• GDG Rishon and AngularUP co-organizer
10. Agenda
• The Redux pattern
• Combining Redux and Angular
• ng2-redux library in a nutshell
11. Known SPA Complexity Solutions
• Command Query Responsibility Segregation (CQRS)
• Event Sourcing
• Flux
• And more
12. Redux
• Design pattern based on Flux
• But it’s not Flux!
• Predictable state container for JavaScript apps
16. State is Read-Only
• The only way to mutate the state is to emit an action describing what
happened
store.dispatch({
type: 'ADD_GROCERY_ITEM',
item: { productToBuy: 'Milk' }
});
store.dispatch({
type: 'REMOVE_GROCERY_ITEM',
index: 3
});
17. Redux Principles
1. Single source of truth
2. State is read-only
3. Changes are made with pure functions
18. Changes Are Made with Pure Functions
• To specify how the state is transformed by actions, you write a pure
function
function groceryItemReducer(state, action) {
switch (action.type) {
case 'ADD_GROCERY_ITEM':
return object.assign({}, state, {
groceryItems: [
action.item,
…state.groceryItems
]
};
default:
return state;
}
}
21. Actions
• Plain JavaScript objects
• Include
• Type – action type
• Payload – the change that should occur
let action = {
type: 'ADD_GROCERY_ITEM',
item: { productToBuy: 'Milk' }
};
Action
Creators
23. Reducers
• Change the state in response to things that happened in the
application
• Pure functions
function groceryItemReducer(state, action) {
switch (action.type) {
case ADD_GROCERY_ITEM:
return object.assign({}, state, {
groceryItems: [
action.item,
…state.groceryItems
]
};
default:
return state;
}
}
Reducers
24. Store
• Only one store object
• Store data accessed through getState function
• Updates only in response to dispatching an action
import {createStore} from ‘redux’;
import {groceryItemReducer} from ‘./reducers/groceryItemReducer’;
const store = createStore(groceryItemReducer);
Store
29. Redux Middleware
• Extension point between dispatching an action and the reducer
• Middleware examples:
• Logging
• Async operations
• Routing
const middleware = store => next => action => {
// do something before dispatcher
let result = next(action);
// do something after dispatcher
return result;
}
const store = createStore(reducer, applyMiddleware(middleware));
32. Angular and Redux
• Redux can be applied in Angular oriented applications
• It’s a data flow pattern
• Popular Angular & Redux libraries:
• ng2-redux
• ngrx/store
34. ng2-redux - Setup
• Add the module
• Create the store and provide it in the main module
import { NgReduxModule, NgRedux } from 'ng2-redux';
@NgModule({
imports: [ /* ... */, NgReduxModule ]
})
class AppModule {
constructor(ngRedux: NgRedux<IAppState>) {
ngRedux.provideStore(store);
}
}
35. ng2-redux - Usage
• Use the @select decorator and dispatch function:
class App {
@select() counter: Observable<number>;
constructor(private ngRedux: NgRedux<IAppState>) {}
increment() {
this.ngRedux.dispatch({ type: INCREMENT});
}
}