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