Angular2 and Redux - up & running - Nir Kaufman - Codemotion Amsterdam 2016

Post on 12-Apr-2017

207 views 2 download

Transcript of Angular2 and Redux - up & running - Nir Kaufman - Codemotion Amsterdam 2016

REDUX & ANGULAR UP & RUNNING

NIR KAUFMAN

AGENDAwhat is redux? how to use redux? where Angular fits in? where to go from here?

WHAT IS REDUX? HOW TO USE IT? HOW ANGULAR FITS IN? NEXT STEPS

WHAT IS REDUX

REDUX IS A DESIGN PATTERNfor managing a complex, ever changing state in a challenging modern single page applications

SINGLE SOURCE OF TRUTHthe state of your whole application is stored within a single store

THE STATE IS READ ONLYthe only way to mutate the state is to emit an action describing what happened

PURE FUNCTIONSto specify how the state is transformed by actions, you write a pure function.

PURE* FUNCTION

ACTION NEXT STATE

* No side-effects

reducer

const currentState = 0; const action = {type: 'INCREASE'}; function reducer(action, currentState){ if(action.type === 'INCREASE') { return currentState + 1; } return currentState; }

const currentState = 0; const action = {type: 'INCREASE'}; function reducer(action, currentState){ if(action.type === 'INCREASE') { return currentState + 1; } return currentState; }

const currentState = 0; const action = {type: 'INCREASE'}; function reducer(action, currentState){ if(action.type === 'INCREASE') { return currentState + 1; } return currentState; }

const currentState = 0; const action = {type: 'INCREASE'}; function reducer(action, currentState){ if(action.type === 'INCREASE') { return currentState + 1; } return currentState; }

const currentState = 0; const action = {type: 'INCREASE'}; function reducer(action, currentState){ if(action.type === 'INCREASE') { return currentState + 1; } return currentState; }

HOW TO USE REDUX

REDUX IS A TINY LIBRARYwhich contains a function for creating a store, and 4 other helpers functions that we can use.

import { createStore } from 'redux'; const store = createStore(reducer);

import { createStore } from 'redux';const store = createStore(reducer);

STORE APIgetState() dispatch(action)subscribe(listener)replaceReducer(reducer)

THE STORE IS SIMPLE TO UNDERSTANDwe can implement a working store in less then 30 lines of code.

function createStore(reducer) { let state = null; const listeners = []; function getState() { return state; } function dispatch(action) { state = reducer(state, action); listeners.forEach(listener => listener()) } function subscribe(listener) { listeners.push(listener); return function () { let index = listeners.indexOf(listener); listeners.splice(index, 1) } } dispatch({ type:’@@INIT' }); return { getState, dispatch, subscribe } }

CONNECTING THE DOTSnow we can dispatch actions and be notified when the state has changed.

dispatch

getStateSTATE

ACTION

STOREUI

UI IS RENDERED

UI IS RENDEREDSOMETHING HAPPENED

UI IS RENDEREDSOMETHING HAPPENEDACTION DISPATCHED

UI IS RENDEREDSOMETHING HAPPENEDACTION DISPATCHEDSTATE CHANGED

UI IS RENDEREDSOMETHING HAPPENEDACTION DISPATCHEDSTATE CHANGEDUI IS RENDERED

UI IS RENDEREDSOMETHING HAPPENEDACTION DISPATCHEDSTATE CHANGEDUI IS RENDEREDSOMETHING HAPPENED

UI IS RENDEREDSOMETHING HAPPENEDACTION DISPATCHEDSTATE CHANGEDUI IS RENDEREDSOMETHING HAPPENEDACTION DISPATCHED

UI IS RENDEREDSOMETHING HAPPENEDACTION DISPATCHEDSTATE CHANGEDUI IS RENDEREDSOMETHING HAPPENEDACTION DISPATCHEDSTATE CHANGED

UI IS RENDEREDSOMETHING HAPPENEDACTION DISPATCHEDSTATE CHANGEDUI IS RENDEREDSOMETHING HAPPENEDACTION DISPATCHEDSTATE CHANGEDSOMETHING HAPPENED

UI IS RENDEREDSOMETHING HAPPENEDACTION DISPATCHEDSTATE CHANGEDUI IS RENDEREDSOMETHING HAPPENEDACTION DISPATCHEDSTATE CHANGED

UI IS RENDEREDSOMETHING HAPPENED

UNI-DIRECTIONAL DATA FLOW

sync flow

{ LIVE CODING }let’s build a traffic light and see redux in action!

INTERCEPTING THE ACTION FLOWthis is done using middleware which can catch the action before they hit the store.

async flow

STATE

ACTION

STOREUI

Middlewae

{ LIVE CODING }implementing a simple logger as a middleware.

ANGULAR & REDUX

JUST THE VIEWapi as actions logic in middlewares & reducers state inside a store

ANGULAR APP IS A TREE OF COMPONENTSeach component is responsible for rendering a a pert of the state, or dispatching actions.

CONTAINER

COMPONENT COMPONENT

STORE

[properties] (events)

actions

state

BINDING COMPONENTS TO THE STOREit’s straightforward but requires a lot of boilerplate inside the component class.

NPM TO THE RESCUE! FIND AN ADAPTORI will use the ‘angular2-redux-bindings’ for this example

class TodoListComponent { constructor(){ this.unsubscribe = store.subscribe( () => this.renderList ) } ngOnInit(){ this.renderList() } ngOnDestroy(){ this.unsubscribe() } addItem(item){ store.dispatch({ type: 'ADD_ITEM', payload: item }) } renderList(){ this.list = store.getState().list; } }

class TodoListComponent { @MapState('list') private list; @BindActions(addItem) private addItem; }

{ LIVE CODING }let’s build the view layer using Angular2 components

NEXT STEPS

PLAY WITH THE DEMO

https://github.com/nirkaufman/angular-redux-demo

Angular & Redux Workshop

https://leanpub.com/redux-book

REDUX BOOK

Angular & Redux Workshop

FURTHER READINGREDUX http://redux.js.org/

https://egghead.io/series/getting-started-with-redux

CQRS & EVENT SOURCING https://msdn.microsoft.com/en-us/library/dn568103.aspx

https://msdn.microsoft.com/en-us/library/dn589792.aspx

ANGULAR 2 angular-2-change-detection-explained.html

THANK YOU!

Read our blog:http://blog.500tech.com

NIR KAUFMANnir@500tech.com

Head of Angular Development @ 500Tech