Table of Contents

About

Redux is a state manager.

Concept

The state inside a store is updated via a dispatch function that takes an action as argument and pass it to a reducer function. The reducer will calculate a new state passing it back to the store that will then:

  • notify the subscribers
  • and log the state change in a history table.

You can subscribe to a store in order to update the UI in response to state changes. For React, you'd use a view binding library (e.g. React Redux) that will take this work from you.

Installation

npm

npm install --save redux
npm install --save-dev redux-devtools

module

The module is available in the dist map : https://unpkg.com/[email protected]/dist/redux.min.js

Redux is then available as the REDUX globale variable

Concept

State

Single source of truth: The state of your whole application is stored in an object tree within a single store.

Debug:

  • An handy way to follow the state is print it after each modification:
store.subscribe(() =>
  console.log(store.getState())
)
  • or the Chrome Redux Dev tool

Redux Devtool Chrome

Action

An action is an plain JavaScript object describing what happened with a mandatory type property. It will then be passed to the reducer function.

Example:

{ 
    type: 'ADD_TODO', 
    text: 'Go to swimming pool' 
}

Reducer

To specify how the actions transform the state tree, you write function called reducers.

A reducer takes an action as input and transforms the state into the next state.

The reducer function signature is

recuder(state, action) => nextState

where:

  • the inputs are the actual state and the action dispatched.
  • returns the next state.

Example:

function counter(state = 0, action) {
  switch (action.type) {
  case 'counter/INCREMENT':
    return state + 1
  case 'counter/DECREMENT':
    return state - 1
  default:
    return state
  }
}

A reducer creates its own context (scope). Therefore if you return an object, you can get it as: state.myReducer.myProperty.
You can have multiple reducer and then multiple context. You need to combine them in one with the CombineReducer function.

Example:

import { combineReducers } from 'redux'
import reducer1 from './reducer1'
import reducer2 from './reducer2'

// Just add a command list after inscription to add more reducer
const appReducer = combineReducers({
    reducer1,
    reducer2
})

export default appReducer

Store

A store is a container that holds the application's global state.

Its API is.

Create

createStore(reducer, [initialState], [enhancer]) where:

  • reducer - A reducing function.
  • initialState - The initial state of the store.
  • enhancer - Can be used to enhance the Redux store and add third-party libraries
let store = createStore(counter)

Subscribe

You can use subscribe() to update the UI in response to state changes. Normally you'd use a view binding library (e.g. React Redux) rather than subscribe() directly. However it can also be handy to persist the current state in the localStorage.

store.subscribe(() =>
  console.log(store.getState())
)

Dispatch

The only way to mutate the internal state is to dispatch an action. The actions can be serialized, logged or stored and later replayed.

let action  = { type: 'INCREMENT' }
store.dispatch(action)

GetState

store.subscribe(() =>
  console.log(store.getState())
)

You can also see the state with the Browser extension

Example

  • The action will have this properties
let action = {
   type: "string" // INCREMENT or DECREMENT
}
  • The reducer. It manipulate the state which is a single variable
function counter(state = 0, action) {
  switch (action.type) {
  case 'INCREMENT':
    return state + 1
  case 'DECREMENT':
    return state - 1
  default:
    return state
  }
};
  • Creating a store with this reducer:
// If used in npm
// import {createStore} from 'redux'
let store = Redux.createStore(counter);
  • Subscribe to the store to see the state
store.subscribe(() =>
  console.log(store.getState())
)
  • Perform an action (dispatch)
store.dispatch({ type: 'INCREMENT' })
// 1
store.dispatch({ type: 'INCREMENT' })
// 2
store.dispatch({ type: 'DECREMENT' })
// 1

Documentation / Reference