Utilisation de Mobx en tant que gestionnaire d'état dans les applications natives React

Publié: 2022-03-10
Résumé rapide ↬ MobX est l'un des nombreux outils de gestion d'état disponibles pour les développeurs React. Dans ce didacticiel, Fortune Kay explique ce qu'est MobX et comment vous pouvez l'utiliser dans vos applications React en en créant une à partir de zéro.

La gestion des états fait partie intégrante du développement d'applications JavaScript, en particulier les applications React et React Native. Dans ce tutoriel, nous allons apprendre à utiliser la bibliothèque MobX pour la gestion des états ; comprendre les concepts de base, certains cas d'utilisation et construire un exemple simple.

Remarque : Une connaissance de base de Javascript et de React Native vous sera très utile tout au long de ce didacticiel.

Utiliser MobX dans les applications React

L'état est les données avec lesquelles votre ou vos composants travaillent - il contient les données dont un composant a besoin et il dicte ce qu'un composant rend. La gestion de l'état est le processus de gestion de la façon dont l'état est mis à jour et transmis d'un composant à un autre. Surveiller et travailler avec des données dans une application peut être difficile et c'est le besoin de bibliothèques de gestion d'état. La gestion de toutes les données de votre application peut être un peu intimidante, en particulier lorsque votre application grandit en taille et en complexité, la création de votre propre outil de gestion d'état n'est pas seulement longue mais difficile, c'est pourquoi vous voudrez peut-être utiliser une bibliothèque de gestion d'état.

Cependant, il est important de savoir que l'état n'est pas la seule donnée rendue par un composant, les composants peuvent également rendre les accessoires qui lui sont transmis.

Options de gestion d'état

Les bibliothèques de gestion d'état pour les applications React Native incluent ; React Context API, Redux, MobX et Unstated Next.

Bien que ces gestionnaires d'état aient chacun leurs avantages et leurs inconvénients, je recommande personnellement MobX en raison de sa simplicité, de son code passe-partout minimal - il ne vous oblige pas à modifier votre code, car dans son cœur, MobX est et ressemble à JavaScript ; vous n'avez pas besoin d'un changement d'architecture pour le supporter (contrairement à Redux et dans une moindre mesure à Context).

En fait, c'est une abstraction tellement invisible que dans de nombreux cas, si vous supprimez tout le code MobX - les décorateurs @observable , @computed , @action et observer , votre code fonctionnera exactement de la même manière (bien qu'il y ait des problèmes de performances ) et il n'est pas limité à un état global. Ce sont quelques raisons d'aller de l'avant avec MobX en tant que gestionnaire d'état de choix pour vos applications React Native.

Bien qu'il soit également important de noter certains problèmes liés à l'utilisation de MobX en tant que gestionnaire d'état, dont certains incluent son évitement des règles sur la façon de l'implémenter et MobX peut être difficile à déboguer, en particulier lorsque vous modifiez l'état directement dans un composant sans utiliser le @actions paramètre.

Qu'est-ce que MobX ?

Selon la documentation officielle, MobX est une bibliothèque éprouvée qui rend la gestion d'état simple et évolutive en appliquant de manière transparente une programmation réactive fonctionnelle. MobX traite votre application comme une feuille de calcul. La logique est que tout ce qui peut être dérivé de l'état de l'application doit être fait automatiquement .

Architecture d'état MobX
Architecture d'état MobX. ( Grand aperçu )
Plus après saut! Continuez à lire ci-dessous ↓

Principes fondamentaux et concept de MobX

MobX se différencie des autres gestionnaires d'état par les concepts suivants.

1. État

L'état correspond aux données que contient votre application - c'est à peu près tout le contenu de sa mémoire. Ceci s'applique également à vos composants.

2. Dérivations

Dans MobX, tout ce qui peut être dérivé de l'état sans interactions est une dérivation. Voici des exemples de dérivations :

  • Interface utilisateur,
  • Modules complémentaires backend tels que les modifications apportées à un serveur.

MobX a deux principaux types de dérivations :

  • Valeurs calculées
    Les valeurs calculées sont principalement des valeurs qui peuvent être dérivées d'un état actuel à l'aide de fonctions pures.
  • Réactions
    Les réactions dans les dérivations sont des effets secondaires qui se produisent à la suite de changements dans l'état de votre application. Ils sont similaires à une valeur calculée, mais au lieu de produire une nouvelle valeur, une réaction produit un effet secondaire pour des choses comme l'impression sur la console, les requêtes réseau, la mise à jour incrémentielle de l'arborescence des composants React pour corriger le DOM, etc.

Une règle d'or lors de l'utilisation de MobX est que lors de la création d'une valeur basée sur l'état actuel, utilisez une valeur calculée.

3. Mesures

Contrairement aux dérivations, les actions sont du code qui provoque des modifications de l'état d'une application, c'est-à-dire du code qui modifie l'état. Ce sont tout ce qui modifie l'état. Avec MobX, vous pouvez le rendre explicite dans votre code, les actions sont principalement des événements utilisateur tels que des entrées, des poussées de données backend ou même des événements planifiés.

Pour mieux comprendre les actions, regardons un exemple de la documentation MobX.

 class Ticker { @observable tick = 0 @action increment() { this.tick++ // 'this' will always be correct } } const ticker = new Ticker() setInterval(ticker.increment, 1000)

Ici, nous définissons un tick @observable avec une valeur initiale de 0. Ensuite, nous avons créé une fonction incrément qui est également une action qui met à jour la valeur initiale une fois qu'un tick est effectué toutes les secondes.

Observables dans MobX

Les observables ou les valeurs observables dans MobX sont principalement des primitives JavaScript, des objets simples, des classes, des tableaux et des cartes. Ils sont principalement utilisés en déclarant d'abord un observable et en lui ajoutant une valeur, puis en l'appelant en ajoutant un @observable comme indiqué ci-dessous :

 observable(value) @observable classProperty = value

Approche d'architecture de magasin dans MobX

L'architecture principale de MobX comprend des parties et des idées telles que des services, des magasins, des modèles de vue et des conteneurs, dont certains sont expliqués ci-dessous.

  • Service
    Il s'agit généralement d'une fonction appelée depuis un conteneur ; ils peuvent être utilisés pour obtenir des données à partir d'API et être ajoutés au magasin.
  • Boutique
    Comme son nom l'indique, il s'agit de la place centrale de l'état utilisé par une application. Habituellement dans MobX, ceux-ci incluent les observables, les variables, les actions et les propriétés calculées.
  • Récipient
    Cela appelle service et place les données de View Model dans View Component en tant @observer ) .

MobX dans React et applications natives

À des fins d'apprentissage, dans ce didacticiel, nous allons créer une application de liste simple qui permettra à un utilisateur d'ajouter, d'afficher et de supprimer des éléments de liste. Nous utiliserons MobX en tant que gestionnaire d'état dans cette application pour ajouter des listes, les mettre à jour et les supprimer de l'état de l'application. Cependant, il est important de noter que vous comprenez déjà les concepts de base de JavaScript et de React.

Sans plus tarder, commençons !

Configuration de votre environnement

Maintenant que nous savons ce qu'est MobX et comment il fonctionne, laissez-moi vous guider dans la configuration de votre projet.

Commençons par créer un projet avec ce qui suit, écrivez le code suivant sur votre terminal pour initialiser un projet :

 npx create-react-app listapp

Le code ci-dessus créera une application React nue à l'aide du package create-react-app. Déplacez-vous dans le répertoire du projet :

 cd listapp

Pour cette application, nous aurons besoin de trois composants :

  • TitleInput
    Celui-ci contiendra le titre de notre projet et un formulaire de saisie pour ajouter des listes.
  • List
    Ce sera un formulaire de saisie qui permettra à un utilisateur d'ajouter une liste. Il aura un bouton Ajouter pour ajouter nos éléments de liste.
  • ListsDisplay
    Ce composant affichera tous les éléments de la liste des utilisateurs ainsi qu'un bouton de suppression généré automatiquement lorsqu'un utilisateur ajoute un élément de la liste.

Nous utiliserons un Store.js pour contenir l'état de l'application et des méthodes pour le modifier similaire à Redux. Précisons à quoi ils serviront.

  • mobx
    Il s'agit du gestionnaire d'état que nous utiliserons pour ce projet.
  • mobx-react
    Ce sont les liaisons React officielles pour MobX.
  • bootstrap
    Nous utiliserons la version 4.5 de bootstrap pour styliser notre projet.
  • uuid
    Ceci est utilisé pour créer automatiquement des clés pour supprimer des listes.

Cela fait, allons-y et installons ces packages. Je vais les installer avec une alternative npm faite en fil :

 yarn add mobx mobx-react [email protected] uuid

Une fois les packages installés, nous allons démarrer notre application en mode développement en exécutant le code ci-dessous dans notre terminal :

 yarn start

Configuration de notre App Store

Créons un magasin pour notre projet. Tout d'abord, créez un fichier dans le répertoire racine de notre projet appelé ListStore , ce sera l'emplacement central de l'état de notre application.

Pour cette application, nous devrons créer un ListStore afin de ne pas nous répéter lorsque nous l'utiliserons dans d'autres composants de l'application.

 /*** src/Store.js ***/ import { observable, action, computed } from "mobx"; import { v4 } from "uuid"; export class List { @observable value @observable done constructor (value) { this.id = v4() this.value = value } } export class ListStore { @observable lists = [] @observable filter = "" @action addList = (value) => { this.lists.push(new List(value)) } @action deleteList = (list) => { this.lists = this.lists.filter(t => t !== list) } @computed get filteredLists () { const matchCase = new RegExp(this.filter, "i") return this.lists.filter(list=> !this.filter || matchCase.test(list.value)) } }

Dans le code ci-dessus, nous avons importé trois fonctions de mobx .

  • observable
    Celui-ci contient une variable qui peut être mise à jour en cas de changement d'état.
  • action
    Utilisé pour modifier l'état de l'application.
  • computed
    Valeurs qui peuvent être dérivées de l'état existant ou d'autres valeurs calculées, elles changent après la modification d'un état.

La classe List a deux valeurs d'objet qui sont done et value qui contiendra l'état initial de l'application et la modification en cas de changement.

Nous voulons que notre nouvelle liste crée automatiquement une clé afin que nous puissions obtenir automatiquement un bouton de suppression une fois qu'une liste est créée, ici uuid est utilisé pour créer automatiquement des clés dans notre application.

Ensuite, nous avons ajouté une fonction addList qui ajoutera des listes lorsque vous cliquerez dessus en utilisant la méthode .push() pour pousser la liste dans le tableau que nous avons déjà créé dans le tableau @observable lists .

La fonction deleteList accepte List comme une propriété censée être l'élément que l'utilisateur souhaite supprimer. Ensuite, nous définissons la valeur de this.Lists sur un nouveau tableau après avoir supprimé l'élément sélectionné.

addLists et deleteList sont des actions car elles modifient l'état de notre application lorsque des modifications sont apportées.

Initialisation du magasin MobX

Le prochain sur notre liste consiste à importer notre magasin dans notre App.js et à l'utiliser dans notre projet.

 import React from 'react'; import Navbar from "./components/navbar"; import ListDisplay from "./components/ListDisplay"; import {ListStore} from './ListStore'; function App() { const store = new ListStore() return ( <div> <Navbar store={store}/> <ListDisplay store={store}/> </div> ); } export default App;

Ici, nous avons importé les composants TitleInput et ListDisplay . Puis nous avons initialisé le store dans notre App.js afin de pouvoir le passer comme props aux composants TitleInput et ListDisplay .

Normalement, cela générera une erreur car nous n'avons pas travaillé sur les autres composants, alors faisons cela. Construisons le composant ListDisplay .

ListDisplay

Ce composant affiche toutes nos listes ajoutées et génère également automatiquement un bouton de suppression une fois qu'une nouvelle liste est ajoutée.

 import React from 'react' import List from "./List"; import { observer } from 'mobx-react'; function ListDisplay(props) { const { deleteList, filteredLists } = props.store return ( <div> <div className="container"> {filteredLists.map(list => ( <List key={list.id} list={list} deleteList={deleteList} /> ))} </div> </div> ) } export default observer(ListDisplay)

Pour ce composant, nous avons créé une fonction ListDisplay et en avons fait un observateur, nous avons également déstructuré les fonctions list et deletelist du store, ce faisant, nous avons facilité leur passage en tant que props d'objet.

Ensuite, nous mappons via filteredLists pour renvoyer les listes, que nous utilisons ensuite pour créer la liste individuelle en transmettant l'élément renvoyé en tant qu'accessoires au composant List .

Une fois cela fait, notre composant devrait ressembler à ceci avec des listes ajoutées :

Le composant d'affichage de liste
Listes affichées par le composant `ListDisplay`. ( Grand aperçu )

Ensuite, ajoutez les composants List et TitleInput .

Composant de liste

Tout comme nos autres composants, notre composant List exportera la liste en tant qu'observateur afin d'aider le magasin à surveiller les modifications.

 import React from 'react' import { observer } from 'mobx-react' function List(props) { return ( <div className="card"> <div className="card-body"> <div className="d-flex justify-content-between align-items-center"> <p className={`title ${props.list.done ? "text-secondary" : ""}`}> {props.list.value} </p> <div> <button onClick={props.deleteList.bind(this, props.list)} className="btn btn-danger font-weight-bold py-2 px-5 ml-2"> Delete </button> </div> </div> </div> </div> ) } export default observer(List)

J'ai utilisé le bootstrap pour créer des cartes dans le premier ensemble de divs et également aligner l'icône de suppression pour se déplacer vers le côté droit de l'application. Tout d'abord, nous avons créé un composant de carte pour gérer notre list , puis nous avons créé une balise de bouton pour le button de suppression qui acceptera deux objets de celui-ci et passera un accessoire à la liste, cela supprimera au clic l'élément de liste sélectionné du listes dans la page.

Le composant liste
Un seul composant de liste avec le bouton de suppression. ( Grand aperçu )

Vient ensuite notre TitleInput qui contiendra notre formulaire de saisie pour ajouter des listes et le titre du projet.

TitleInput

Comme pour nos autres projets, nous ajouterons une fonction @observer afin que le composant puisse accepter les accessoires de l'App Store.

 import React, { useState } from 'react' import { observer } from 'mobx-react' function Navbar(props) { const [value, setValue] = useState("") const {addList} = props.store const prepareAddList = (e) => { e.preventDefault() addList(value) setValue("") } return ( <div className="container mt-3"> <h1 className="title">List App</h1> <form onSubmit={prepareAddList} className="form-group"> <div className="row ml-lg-2"> <input className="form-control-lg col-12 col-lg-9 col-sm-12 mr-3 border border-secondary" value={value} type="text" onChange={(e) => setValue(e.target.value)} placeholder="Enter list" /> <button className="col-lg-2 col-5 col-sm-5 mt-2 mt-lg-0 mt-sm-2 btn btn-lg btn-success font-weight-bold"> Add to List </button> </div> </form> </div> ) } export default observer(Navbar)

Tout d'abord, nous avons initialisé un état initial. À l'aide de React Hooks, nous avons ajouté un état initial appelé values que nous avons défini sur une chaîne vide. Nous l'utilisons pour conserver la valeur de ce qui est entré dans le champ de saisie. Pour en savoir plus sur React Hooks, vous pouvez consulter cet article de David Abiodun.

Ensuite, nous avons appelé un objet pour ajouter des listes au magasin addList et l'avons transmis en tant qu'accessoires de l'App Store.

Ensuite, nous avons créé une fonction preparedAddList pour accepter un objet événement pour les formulaires de saisie, nous avons également ajouté un bouton pour ajouter les listes manuellement au clic.

Presque terminé, nous devons redémarrer notre serveur de projet en exécutant :

 yarn start

Et notre TitleInput devrait ressembler à ceci :

Une entrée de titre
Titre et composant d'entrée. ( Grand aperçu )

Nous en avons maintenant terminé avec tous nos composants d'application, alors assemblons-les dans notre App.js . Pour ce faire, nous devons importer nos composants titleInput et ListDisplay . Nous devons également importer notre magasin à partir du composant Store.

Pour que MobX fonctionne dans notre application, nous devons transmettre le magasin MobX en tant qu'accessoires dans notre application et composants individuels afin qu'ils obtiennent les propriétés et les fonctions du magasin.

 import React from 'react'; import Navbar from "./components/navbar"; import ListDisplay from "./components/ListDisplay"; import {ListStore} from './ListStore'; function App() { const store = new ListStore() return ( <div> <Navbar store={store}/> <ListDisplay store={store}/> </div> ); } export default App;

Notre application devrait ressembler à ceci une fois terminée :

Application de liste terminée
( Grand aperçu )

Conclusion

MobX est un excellent gestionnaire d'état, en particulier pour les applications basées sur React, en construisant notre application de liste, nous avons appris les concepts de base de MobX, l'état, les dérivations et les actions. Une version de travail de cette application peut être trouvée ici :

Vous pouvez aller plus loin en utilisant MobX dans la prochaine application que vous créez et qui implique la gestion de l'état. J'aimerais voir quelles nouvelles choses vous proposez. Vous pouvez en savoir plus sur MobX et les applications de gestion d'état dans les références ci-dessous.

Ressources et références

  • "Réagissez nativement avec MobX - Premiers pas", Nader Dabit, moyen
  • « Concepts & Principes » MobX (documentation officielle)
  • "Meilleures pratiques avec React Hooks", Adeneye David Abiodun, Smashing Magazine