Précédent: Initiation à React (5/5)

Suivant: Gestion de l'état dans React avec Redux (2/5)

Gestion de l'état dans React avec Redux (1/5)

Ce tutoriel prend la suite du précédent, qui présentait de manière basique ce qu'était une application React.

Les sources pour démarrer sont donc celles de la fin du premier tuto : https://github.com/falkodev/tuto-symfony-react-webpack-babel

Dans le tutoriel présent, nous allons découvrir l'intérêt et le rôle d'une architecture gérant l'état des objets. Il en existe plusieurs telle que Mobx, s'appuyant sur le pattern Observer. Nous étudierons Redux, qui s'inspire de Flux, l'architecture poussée par le créateur de React : Facebook.

C'est quoi cet état et pourquoi le gérer ?

Dans une application web moderne, nous gérons des tas d'éléments comme :

  • la connexion utilisateur
  • des formulaires
  • des droits utilisateur sur des pages
  • l'ajout, la modification et l'affichage de données (le fameux CRUD)
  • ...

Ces éléments sont contenus dans des objets au sein d'une application React. Comment savoir dans toutes les pages de l'application si :

  • un utilisateur est connecté
  • un formulaire est validé
  • l'utilisateur en cours a le droit d'accès à la page
  • la modification d'une donnée en base est bien répercutée en front pour être réactualisée
  • .... ?

Il faut gérer l'état de ces objets (state management en anglais) et le conserver tout au long de la vie de l'application. C'est là qu'entrent en jeu des architectures pour traiter les changements d'états.

En plus de React - qui est assimilé au V dans le pattern design MVC - Facebook a créé l'architecture Flux. Elle utilise le concept de flux unidirectionnel de données (contrairement à Angular ou Vue qui sont sur un double-way data binding) : cela signifie que toutes les données d'une application suivent le même modèle de cycle de vie, rendant la logique dans l'app plus prévisible et simple à comprendre. Cela encourage aussi l'unicité des données, pour ne pas avoir des versions multiples et indépendantes de la même donnée.

Cette architecture est structurée ainsi:

  • Actions – Des méthodes qui vont passer des données au Dispatcher
  • Dispatcher – Reçoit les actions et renvoit des charges utiles (payloads) à des fonctions de rappel (callbacks) enregistrées au préalable
  • Stores – Contient l'état de l'application et la logique des fonctions de rappel enregistrées dans le Dispatcher
  • Controller Views – Des composants React qui chargent l'état depuis le ou les Stores et le passent à des composants enfants.

Un article bien clair à ce sujet : http://putaindecode.io/fr/articles/js/flux/

Tout ceci peut paraître flou encore pour l'instant, mais avec l'utilisation de Redux, les choses s'éclairciront.

Architecture

Redux est donc une des implémentations de Flux. La confusion régnait jusqu'en 2015 sur l'implémentation Flux maitresse à choisir sur un projet React, il y en avait des dizaines. Dan Abramov, jeune développeur avec de l'expérience des frameworks utilisant la programmation fonctionnelle comme paradigme de base, est arrivé avec sa solution Redux et a époustouflé tout le monde à l'époque. Elle utilise des concepts utilisés en masse dans Elm, tels que l'immutabilité ou les fonctions pures pour gérer l'état des objets.

Redux est basé sur des reducers (d'où le nom) pour gérer les objets dans ce qui est appelé l'état en Redux (state). Il ne modifie pas un objet mais utilise des fonctions pures pour créer un nouvel objet et l'ajouter à l'état. Il utilise aussi un seul store, divisé par plusieurs reducers.

Alors qu'est-ce qu'un reducer ? Pour répondre, il faut déjà parler des fonctions pures. C'est un concept de programmation fonctionnelle : ce sont des fonctions qui avec les mêmes paramètres renvoient toujours la même réponse. Ce devrait être le principe de toute fonction en fait.

Parfois, des fonctions deviennent des fourre-tout, avec beaucoup de conditions, longues et peu lisibles, donc sources potentielles de bugs et difficiles à tester. Les fonctions pures sont courtes et ne font qu'une chose : renvoyer la même réponse selon un contexte donné. Un très bon article à ce sujet : http://www.nicoespeon.com/fr/2015/01/fonctions-pures-javascript/

Un reducer devrait donc être une fonction pure, dans la théorie Redux. La librairie Immutable.js n'est pas obligatoire mais convient bien à un projet de ce genre.

Il est temps d'installer les packages nécessaires :

npm i immutable react-redux@4.4.5 redux@3.5.2 redux-form@5.2.5 --save

Pour ceux qui démarrerait un projet from scratch, il suffit de prendre le fichier package.json des sources finales et de faire un npm install

Sujet de l'application

La plupart des tutoriels présentant Redux le font dans le cadre d'une appli de "to-do", de gestion de tâches.

Le sujet de notre appli sera différent, ce sera la gestion d'une classe numérique. Notre application va permettre de gérer, très basiquement, une liste d'étudiants.

Le prochain billet détaillera la mise en place de Redux dans notre fichier app.js.

Précédent: Initiation à React (5/5)

Suivant: Gestion de l'état dans React avec Redux (2/5)