fbpx

Redux: actions, reducers, et store sans maux de tête

Cette série d’articles est consacrée à la gestion d’état dans une application ReactJS  qui est l’une des technologies les plus utilisées à Transversall.

Le but de ce tutoriel est de présenter les principales fondamentales de gestion d’état d’une application JavaScript. Les développeurs ont l’habitue de sauter directement sur le code pour apprendre sans maîtriser la philosophie derrière la technologie qu’ils utilisent. Du coup au moindre bug, il est difficile de savoir par où commencer. Il est également difficile de contribuer à un projet open source lorsqu’on n’a qu’une vague idée de ses fondations.

L’un des gros challenges quand on développe avec ReactJS est la gestion de l’état de l’application. Comment les données sont manipulées ainsi que leur impact sur le rendu de l’application est un point important qu’il convient de maîtriser pour limiter les problèmes de perfomance. C’est là que Redux vient à la rescousse. Il s’agit d’une librairie JavaScript dont la philosophie repose sur trois principes fondamentaux: les actions, les reducers (reducteurs en français sale), et le store (magasin en français approximatif).

Les actions

Imaginez que vous admnistrez le panel d’un site e-commerce. Des exemples d’action que vous initiez au quotidien sont l’ajout d’un produit, la suppression d’un produit, consulter la liste des produits. Chacune de ses actions diffèrent par leur type : ajout de produit, suppression de produit, consulter liste des produits. A chaque fois également que vous initiez l’une de ses actions, des données entre jeu. Dans le cas de l’ajout d’un produit, nous avons par exemple le nom du produit ainsi que son prix. En JavaScript une action se définit comme un pur objet répondant aux règles suivant:

  • La présence de la propriété type pour spécifier le type d’action initié
  • Les données optionnelles qui entrent en jeux. La liberté est laissé au développeur de définir celles à sa convenance

Un example d’action ressemble donc à ceci:

const addProductAction = {
    type: 'ADD_PRODUCT',
    payload:{
        name: 'hat',
        price: 12
    }
}

Il est  aussi possible de définir une action à l’aide d’une fonction retournant un objet. Cette approche à l’avantage de rendre l’action testable. On obtient alors ceci:

const addProductAction = (nameInput, priceInput ) => ({
    type: 'ADD_PRODUCT',
    payload:{
        name: nameInput,
        price: priceInput
    }
})

Les reducers

Vous aviez initié l’action d’ajout d’un produit sur votre plateforme e-commerce. Le traitement qui sera fait ensuite pourrait être l’enchaînement suivant: vérifier que l’utilisateur à le droit d’exécuter ce type d’action, valider les données et les stocker en base de données. Ce traitement est effectué par une fonction. Avec Redux, elle s’appelle reducer. Le reducer a donc pour rôle de fournir un traitement à une action en fonction de son type. Il répond aux règles suivantes:

  • un reducer prend en paramètre un état précédent (imaginer le cas d’une mise à jour) et une action
  • le réduceur retourne un nouvel état en remplacement de l’état précédent en fonction du type d’action

Un exemple de reducer donnerait ceci:

const addProductReducer = (state ={name:"empty", price:0}, action) =>{
    switch (action.type){
        case 'ADD_PRODUCT':
            // processing
            return {name:action.payload.name, price:action.payload.price}
        default:
            return state
    }
}

L’état initial ici est l’objet:

{name:"empty", price:0}

Et après traitement c’est un nouvel état qui est renvoyé:

{name:action.payload.name, price:action.payload.price}

Dans le cas échéant l’état précédent est retourné.

Le store

Le rôle du store est de conserver l’état global de l’application. Il répond aux spécifications suivantes:

  • Il récupère l’état global de l’application à partir des reducers
  • Il reçoit et transmet aux reducers les actions de modification de l’état de l’application
  • Il ne peut y avoir qu’un seul store par application

Un exemple de store donnerait ceci:

const store = createStore(addProductReducer)

Il est du coup possible de récuperer l’état de l’application avec :

store.getState()

Et d’initier une action à l’aide de la méthode dispatch comme ceci:

store.dispatch(addProductAction("hat", 12))

Voilà c’est tout pour les principes fondamentaux de Redux! En résumé, une action définit ce qui va se passer, le reducer s’occupe de comment cela va se passer, le store contient l’état globale de l’application .

    Leave Your Comment Here