Utilisation de Mobx en tant que gestionnaire d'état dans les applications natives React
Publié: 2022-03-10La 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 .
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 appelleservice
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 :
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.
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 :
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 :
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