Gérez l'état de vos applications JavaScript avec Redux

 

ChtiJS #15 - 25/02/16

          @zoontek

  • Développeur chez Colisweb
  • Ruby, Javascript (React Native)
  • Scala sous peu, ça serait cool

“ J'entends beaucoup parler de Flux, de Redux et autres en ce moment 

“ Mais ça répond à quel problème, bordel ? 

#JSfatigue #FlegmeDeChercher

import React, {
  Component,
  PropTypes
} from 'react'

class Basket extends Component {
  static propTypes = {
    products: PropTypes.array,
    totalPrice: PropTypes.number,
  };

  }

export default Basket
import React, {
  Component,
  PropTypes
} from 'react'

class Product extends Component {
  static propTypes = {
    name: PropTypes.string,
    imageSrc: PropTypes.string,
    onBuy: PropTypes.func,
  };

  }

export default Product

Angular 1.x

Faisons en sorte qu'il ne soit pas mort pour rien.

Apprenons de nos erreurs.

Au commencement, Facebook a créé flux

Une architecture plus qu'une vraie librairie

let _todos = []

let TodoStore = Object.assign({}, EventEmitter.prototype, {
  getAll() {
    return _todos
  }
})

AppDispatcher.register(function(action) {
  switch (action.type) {
    case actionTypes.TODO_CREATE:
      const text = action.text.trim()
      _todos.push(text)
      TodoStore.emitChange()
  }
})

export default TodoStore

Donc, malheureusement…

  • Trop de boilerplate code
  • Stores stateful, donnée "mutée"
  • Peu prédictif, complexe à tester
  • Pas de server-side rendering

BEAUCOUP d'implémentations

(previousState, action) => newState

reduce((accumulator, value) => accumulator)

Appelons donc ça un reducer

Un seul state, un seul store

import { combineReducers } from 'redux'
import { createStore } from 'redux'

De multiples reducers, qui gèrent chacun une partie du state

De multiples actions

“ Je ne comprends toujours pas comment tout cela s'articule. ”

– L'intégralité de l'audience

(sauf ceux qui connaissent déjà Redux)

// action

const actionTypes = {
  ADD_TODO: 'ADD_TODO'
}

const addTodo = text => ({
  type: actionTypes.ADD_TODO,
  text
})
// reducer

const todos = (state = [], action) => {
  switch (action.type) {
    case actionTypes.ADD_TODO:
      return [...state, action.text]
    default:
      return state
  }
}
// store

import { createStore } from 'redux'

const store = createStore(todos)

// Log the initial state
console.log(store.getState())

// Every time the state changes, log it
const unsubscribe = store.subscribe(() => {
  console.log(store.getState())
})

// Dispatch some actions
store.dispatch(addTodo('Learn actions'))
store.dispatch(addTodo('Learn reducers'))
store.dispatch(addTodo('Learn store'))

// Stop listening to state updates
unsubscribe()
// store

import {
  createStore,
  combineReducers
} from 'redux'

const reducers = combineReducers(todos)
const store = createStore(reducers)

// Log the initial state
console.log(store.getState())

// Every time the state changes, log it
const unsubscribe = store.subscribe(() => {
  console.log(store.getState())
})

// Dispatch some actions
store.dispatch(addTodo('Learn actions'))
store.dispatch(addTodo('Learn reducers'))
store.dispatch(addTodo('Learn store'))

// Stop listening to state updates
unsubscribe()

Les middlewares

redux-logger

redux-devtools

redux-thunk

// action

const actionTypes = {
  ADD_TODO: 'ADD_TODO'
}

const addTodo = text => ({
  type: actionTypes.ADD_TODO,
  text
})

const addTodoAfter = (text, delay) => (dispatch, getState) => {
  setTimeout(() => {
    // Yay! Can invoke sync or async actions with `dispatch`
    dispatch(addTodo(text));
  }, delay);
}
// action

const actionTypes = {
  ADD_TODO: 'ADD_TODO'
}

const addTodoAfter = (text, delay) => (dispatch, getState) => {
  setTimeout(() => {
    dispatch({
      type: actionTypes.ADD_TODO,
      text
    });
  }, delay);
}
import { applyMiddleware, createStore } from 'redux'
import thunk from 'redux-thunk'
import createLogger from 'redux-logger'
import reducers from '../reducers'

const store = applyMiddleware(thunk, createLogger())(createStore)
export default store(reducers)

Et beaucoup d'autres…

  • redux-promise
  • react-redux
  • redux-react-router
  • redux-storage
  • redux-diff-logger
  • etc, etc, etc.

L'exemple de react-redux

Pour Angular 2: ng2-redux

Merci de votre attention


Questions ?

Tout de suite ? Il suffit de lever la main

Plus tard ? Suis moi sur twitter: @zoontek

Présentation de Redux

By Mathieu Acthernoene

Présentation de Redux

  • 3,318