Jesús Quintana

@marduke182

@marduke182

Barcelona

Digital Origin

Basic Redux

What this talk is not

  • Complex application
  • Side Effects
  • React

What this talk is

  • What redux solves?
  • The principles of redux
  • Middlewares
  • A working example

State

State

  • Web Services responses
  • User interaction
    • Modals
    • Inputs
  • Web Environment
  • Routes, navigation, etc.

Problem: State is hard

  • Sharing information
  • Keeping the application updated 
  • Replicating issues
  • Debugging

Current solutions

Stateful components (this.state)

Services / Factories / Providers / $scope

Ember Data or Services

Backbone Models

  • These solutions don't scale well

  • Bugs are hard to replicate (non deterministic)

  • Tied to frameworks (Hard to migrate)

  • Prone to errors

Caveats

Redux to the Rescue

It's a predictable state container that runs in any javascript environment

The Principles

 

  • The state tree will be stored in a single Javascript Object
  • The state tree is read-only and the only way to change it is through an action
  • Changes are explicit and executed by a pure function called reducer.

The State tree

  • Read only
  • The whole state of your application as a single Javascript Object

The State tree

let initialState = {
    peanut: {
        skin: 'white',
        hair: 'black',
        eyes: 'normal',
        glasses: 'white',
        mouth: 'big',
        shirt: 'yelow_black_jacket',
        pants: 'black_jeans',
        shoes: 'black_white'
    },
    setting: {
        place: "outside",
        time: "9:00am",
        season:"SUMMER"
    }
};

Dispatch an action

  • Plain Javascript Object
  • Describes the change with his minimum representation
  • Only requirement: has a type property
const winterIsComing = { 
    type: 'CHANGE_SEASON',
    season: 'WINTER'
};

const goToSchool = { 
    type: 'CHANGE_PLACE',
    place: 'school'
};

const incrementByAction = { 
    type: 'CHANGE_HAIR',
    colour: 'green'
};

Dispatch an action

winterIsComing

goToSchool

Reducer 

  • It's a function with this signature (currentState, action) => newState
  • Must be a pure function
    • Arguments don't mutate
    • Without Side Effects
    • Deterministic

Reducer 


function setting(state, action) {
    if (typeof state === 'undefined') {
      return settingInitialState;
    }
    switch (action.type) {
      case 'CHANGE_SEASON':
        return Object.assign({}, state, {season: action.season});
      default:
        return state
    }
}

Reducer 

winterIsComing

The reducer function

{
...
    settings: {
        ...
        season: 'SUMMER'
    }
}
{
...
    settings: {
        ...
        season: 'winter'
    }
}


{ 
    type: 'CHANGE_SEASON',
    season: 'WINTER'
}

Why is this a good idea?

Lets talk about DX

  • Time Travel
  • Replay
  • Hot Module Replacement
  • Easy to test
  • Simplicity

What about side Effects

This talk is not about them :D.. But yes, we can handle that too.

 

 

And we use a middleware for that.

Middlewares

Middlewares in redux work in a similar fashion than in express. It is something that goes between dispatching an action, and the moment it's handled by the reducer

(\{ getState, dispatcher\})
({getState,dispatcher})(\{ getState, dispatcher\})
=> (nextMiddleware)
=>(nextMiddleware)=> (nextMiddleware)
=> (action)
=>(action)=> (action)

Middlewares

winterIsComing

Middlewares

Dispatcher

All together

import { createStore, applyMiddleware } from 'redux';
import reducer from './myReducer';
import thunk from 'redux-thunk';

const initialState = { counter: 0 };

const store = createStore(reducer, initialState, applyMiddleware(thunk));

store.subscribe(() => {
    // Here i could update my javascript application.
    console.log(store.getState());
})

store.dispatch({ type: 'INCREMENT'});

// Must log { counter: 1 }

Basic Redux

By Jesus Quintana