redux data flow with angular

Post on 28-Jan-2018

190 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

REDUX DATA FLOW WITH ANGULAR

SPAs Are Complex

Service

Component

Service

ComponentComponent

Service

Component

Service

ComponentComponent

Component

Component

Service

Service Component

Service

Service

Component

Service

ComponentComponent

Component

Component

Service

Service Component

Service

Service

Component

Service

ComponentComponent

Component

Component

Service

Service Component

Service

Service

Component

Service

ComponentComponent

Component

Component

Service

Service Component

Service

Then you make a small change…

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

Agenda

• The Redux pattern

• Combining Redux and Angular

• ng2-redux library in a nutshell

Known SPA Complexity Solutions

• Command Query Responsibility Segregation (CQRS)

• Event Sourcing

• Flux

• And more

Redux

• Design pattern based on Flux• But it’s not Flux!

• Predictable state container for JavaScript apps

Redux Principles

1. Single source of truth

Single Source of Truth

• The application state is stored in an object tree within a single store

let state = store.getState();

Redux Principles

1. Single source of truth

2. State is read-only

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

});

Redux Principles

1. Single source of truth

2. State is read-only

3. Changes are made with pure functions

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;

}}

Let’s drill down

Redux Actors

Action Creators

View

ReducersStore

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

Action Creators

• Functions that return actions

const ADD_GROCERY_ITEM = 'ADD_GROCERY_ITEM';

function addGroceryItem(item) {return {

type: ADD_GROCERY_ITEM,item: item

};}

Action Creators

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

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

Redux Data Flow

Action Creators

View

ReducersStore

interaction (click, mouse etc.)

dispatch(action) (previous state, action)

(new state)(current state)

Redux Data Flow – Cont.

Action Creators

View

ReducersStore

interaction (click, mouse etc.)

dispatch(action) (previous state, action)

(new state)(current state)

Outside Action (push, Ajax callback

and etc.)

Redux Library API

• Redux is a small and compact library:• createStore(reducer)

• combineReducers(reducers)

• applyMiddleware(middlewares)

• compose(functions)

• bindActionCreators(creators, dispatch)

• Store API:• store.dispatch(action)

• store.getState()

• store.subscribe(listener)

DEMO: REDUX IN ACTION

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 dispatcherreturn result;

}

const store = createStore(reducer, applyMiddleware(middleware));

DEMO: REDUX MIDDLEWARE

WHAT ABOUT ANGULAR?

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

NG2-REDUXhttps://github.com/angular-redux/ng2-redux

npm install --save ng2-redux

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);}

}

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});

}}

DEMO: REDUX + ANGULAR

Summary

• Redux • Is a data flow design pattern

• Reduces complexity when building big SPAs

• Can be applied in Angular apps

Resources

• Redux:https://github.com/reactjs/redux

• ng2-redux: https://github.com/angular-redux/ng2-redux

• ngrx/store:https://github.com/ngrx/store

• My Blog – http://www.gilfink.net

• Follow me on Twitter – @gilfink

Thank You!

top related