Utilizarea Mobx ca manager de stat în aplicațiile native React

Publicat: 2022-03-10
Rezumat rapid ↬ MobX este unul dintre numeroasele instrumente de gestionare a stării disponibile pentru dezvoltatorii React. În acest tutorial, Fortune Kay explică ce este MobX și cum îl puteți utiliza în aplicațiile dvs. React, creând una de la zero.

Managementul statului este o parte integrantă a dezvoltării aplicațiilor JavaScript, în special a aplicațiilor React și React Native. În acest tutorial, vom învăța cum să folosim biblioteca MobX pentru gestionarea statului; înțelegeți conceptele de bază, unele cazuri de utilizare și construiți un exemplu simplu.

Notă: cunoștințele de bază despre Javascript și React Native vor fi de mare beneficiu pe măsură ce lucrați prin acest tutorial.

Utilizarea MobX în aplicațiile React

Statul este datele cu care lucrează componenta (componentele) dvs. - deține datele pe care le necesită o componentă și dictează ce redă o componentă. Managementul de stat este procesul de gestionare a modului în care statul este actualizat și trecut de la o componentă la alta. Monitorizarea și lucrul cu datele dintr-o aplicație poate fi dificil și aceasta este necesitatea bibliotecilor de management de stat. Gestionarea tuturor datelor pentru aplicația dvs. poate fi puțin descurajantă, mai ales atunci când aplicația dvs. crește în dimensiune și complexitate, construirea propriului instrument de gestionare a statului nu este doar consumatoare de timp, ci și dificilă. Acesta este motivul pentru care ați putea dori să utilizați o bibliotecă de management de stat.

Cu toate acestea, este important să știți că starea nu este singura dată pe care o componentă le redă, componentele pot, de asemenea, reda elemente de recuzită transmise acesteia.

Opțiuni pentru managementul statului

Bibliotecile de management de stat pentru aplicațiile React Native includ; React Context API, Redux, MobX și Unstated Next.

Deși acești manageri de stat au fiecare avantajele și dezavantajele lor, eu personal recomand MobX datorită simplității sale, codului standard minim - nu necesită să vă schimbați codul, asta pentru că în nucleul său, MobX este și arată ca JavaScript; nu aveți nevoie de o schimbare de arhitectură pentru a o susține (spre deosebire de Redux și într-o măsură mai mică de Context).

De fapt, este o abstracție atât de invizibilă încât, în multe cazuri, dacă scoți tot codul MobX - decoratorii @observable , @computed , @action și observator , codul tău va funcționa exact la fel (deși va avea unele probleme de performanță ) și nu se limitează la un stat global. Acestea sunt câteva motive pentru a merge mai departe cu MobX ca manager de stat ales pentru aplicațiile dvs. React Native.

Deși este, de asemenea, important să rețineți câteva probleme legate de utilizarea MobX ca manager de stat, unele dintre acestea includ evitarea regulilor privind modul de implementare a acestuia, iar MobX poate fi dificil de depanat, mai ales atunci când schimbați starea direct într-o componentă fără a utiliza @actions parametru.

Ce este MobX?

Conform documentației oficiale, MobX este o bibliotecă testată în luptă care face managementul de stat simplu și scalabil prin aplicarea transparentă a programării reactive funcționale. MobX tratează aplicația dvs. ca pe o foaie de calcul. Logica este că orice poate fi derivat din starea aplicației ar trebui făcut automat .

Arhitectura de stat MobX
Arhitectura de stat MobX. (Previzualizare mare)
Mai multe după săritură! Continuați să citiți mai jos ↓

Principiile de bază și conceptul MobX

MobX se diferențiază de alți manageri de stat cu următoarele concepte.

1. Stat

Starea sunt datele pe care le deține aplicația dvs. - este aproximativ întregul conținut al memoriei sale. Acest lucru este valabil și pentru componentele dvs.

2. Derivații

În MobX, orice poate fi derivat din stare fără interacțiuni este o derivare. Exemple de derivări includ:

  • Interfața cu utilizatorul,
  • Suplimente de backend, cum ar fi modificările aduse unui server.

MobX are două tipuri principale de derivații:

  • Valori calculate
    Valorile calculate sunt în mare parte valori care pot fi derivate dintr-o stare curentă folosind funcții pure.
  • Reacții
    Reacțiile în derivări sunt efecte secundare care apar ca urmare a modificărilor stării aplicației dumneavoastră. Sunt similare cu o valoare calculată, dar în loc să producă o nouă valoare, o reacție produce un efect secundar pentru lucruri precum imprimarea pe consolă, efectuarea de solicitări de rețea, actualizarea progresivă a arborelui componente React pentru a corela DOM și așa mai departe.

O regulă de aur atunci când utilizați MobX este că atunci când creați o valoare bazată pe starea curentă, utilizați o valoare calculată.

3. Acțiuni

Spre deosebire de derivări, acțiunile sunt cod care provoacă modificări în starea unei aplicații - cod care schimbă starea. Sunt tot ce modifică statul. Cu MobX, puteți face acest lucru explicit în codul dvs., acțiunile sunt în mare parte evenimente ale utilizatorului, cum ar fi intrări, transferuri de date backend sau chiar evenimente programate.

Pentru a înțelege mai bine Acțiunile, să ne uităm la un exemplu din documentația MobX.

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

Aici, setăm o bifă @observable cu o valoare inițială de 0. Apoi, am creat o creștere a funcției care este, de asemenea, o acțiune care actualizează valoarea inițială odată ce o bifare este făcută în fiecare secundă.

Observabile în MobX

Observabilele sau valorile observabile în MobX sunt în mare parte primitive JavaScript, obiecte simple, clase, matrice și hărți. Ele sunt utilizate în principal prin declararea mai întâi a unui observabil și adăugarea unei valori la acesta și apoi apelarea acestuia prin adăugarea unui @observable, așa cum se arată mai jos:

 observable(value) @observable classProperty = value

Abordarea arhitecturii magazinului în MobX

Arhitectura principală MobX include părți și idei precum servicii, magazin, vizualizare modele și containere - dintre care unele sunt explicate mai jos.

  • Serviciu
    Aceasta este de obicei o funcție numită dintr-un container; pot fi folosite pentru a obține date de la API-uri și pot fi adăugate în magazin.
  • Magazin
    După cum sugerează și numele, acesta este locul central al statului utilizat de o aplicație. De obicei, în MobX, acestea includ observabile, variabile, acțiuni și proprietăți calculate.
  • Container
    Acest lucru apelează service și pune datele din View Model în View Component ca elemente de recuzită React (ar trebui să fie marcate cu @observer decorator).

MobX în React și aplicații native

În scopuri de învățare, în acest tutorial, vom construi o aplicație simplă de listă, care va permite unui utilizator să adauge, să vizualizeze și să șteargă elemente din listă. Vom folosi MobX ca manager de stat în această aplicație pentru a adăuga liste, a le actualiza și a le șterge din starea aplicației. Cu toate acestea, este important să rețineți că înțelegeți deja conceptele de bază ale JavaScript și React.

Fără alte prelungiri, să începem!

Configurarea mediului

Acum că știm ce este MobX și cum funcționează, permiteți-mi să vă ghidez prin configurarea proiectului.

Mai întâi, să creăm un proiect cu următoarele, scrieți următorul cod pe terminalul dvs. pentru a inițializa un proiect:

 npx create-react-app listapp

Codul de mai sus va crea o aplicație React simplă folosind pachetul create-react-app. Mutați în directorul de proiect:

 cd listapp

Pentru această aplicație, vom avea nevoie de trei componente:

  • TitleInput
    Acesta va conține titlul proiectului nostru și un formular de intrare pentru adăugarea listelor.
  • List
    Acesta va fi un formular de introducere care ar permite unui utilizator să adauge o listă. Va avea un buton de adăugare pentru a adăuga elementele din listă.
  • ListsDisplay
    Această componentă va afișa toate elementele listei de utilizatori și, de asemenea, un buton de ștergere care este generat automat atunci când un utilizator adaugă un element din listă.

Vom folosi un Store.js pentru a conține starea aplicației și metode pentru ao modifica similar cu Redux. Să schițăm pentru ce vor fi folosite.

  • mobx
    Acesta este managerul de stat pe care îl vom folosi pentru acest proiect.
  • mobx-react
    Acestea sunt legăturile oficiale React pentru MobX.
  • bootstrap
    Vom folosi versiunea bootstrap 4.5 pentru a ne stila proiectul.
  • uuid
    Acesta este folosit pentru a crea automat chei pentru ștergerea listelor.

După ce am făcut asta, să mergem mai departe și să instalăm aceste pachete. Le voi instala cu o alternativă npm făcută în fire:

 yarn add mobx mobx-react [email protected] uuid

Odată ce pachetele sunt instalate, vom porni aplicația noastră în modul de dezvoltare, rulând codul de mai jos în terminalul nostru:

 yarn start

Configurarea magazinului nostru de aplicații

Să creăm un magazin pentru proiectul nostru. Mai întâi, creați un fișier în directorul rădăcină al proiectului nostru numit ListStore , aceasta va fi locația centrală a stării aplicației noastre.

Pentru această aplicație, va trebui să creăm un ListStore pentru a nu ne repeta atunci când îl folosim în alte componente ale aplicației.

 /*** 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)) } }

În codul de mai sus, am importat trei funcții din mobx .

  • observable
    Aceasta deține o variabilă care poate fi actualizată în cazul unei schimbări de stare.
  • action
    Folosit pentru a modifica starea aplicației.
  • computed
    Valori care pot fi derivate din starea existentă sau din alte valori calculate, se schimbă după ce o stare este modificată.

List de clasă are două valori de obiect care sunt done și value care va menține starea inițială a aplicației și modificarea în cazul modificărilor.

Dorim ca noua noastră listă să creeze automat o cheie, astfel încât să putem obține automat un buton de ștergere odată ce o listă este creată. Aici uuid este folosit pentru a crea automat chei în aplicația noastră.

Apoi, am adăugat o funcție addList care va adăuga liste atunci când se face clic folosind metoda .push() pentru a împinge lista în tabloul pe care l-am creat deja în @observable lists .

Funcția deleteList acceptă List ca o proprietate care ar trebui să fie elementul pe care utilizatorul dorește să-l elimine. Apoi setăm valoarea this.Lists la o nouă matrice după ce am eliminat elementul selectat.

Atât addLists , cât și deleteList sunt acțiuni, deoarece modifică starea aplicației noastre atunci când se fac modificări.

Se inițializează Magazinul MobX

Următorul pe lista noastră este să importam magazinul nostru în App.js și să îl folosim în proiectul nostru.

 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;

Aici am importat componentele TitleInput și ListDisplay . Apoi am inițializat magazinul în App.js -ul nostru pentru a-l putea transmite ca elemente de recuzită componentelor TitleInput și ListDisplay .

În mod normal, aceasta va genera o eroare deoarece nu am lucrat la celelalte componente, așa că hai să facem asta. Să construim componenta ListDisplay .

ListDisplay

Această componentă afișează toate listele noastre adăugate și, de asemenea, generează automat un buton de ștergere odată ce este adăugată o nouă listă.

 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)

Pentru această componentă, am creat o funcție ListDisplay și am făcut din ea un observator, am destructurat și funcțiile list și deletelist din magazin, prin aceasta, am făcut mai ușor să trecem apoi ca obiect de recuzită.

Apoi, mapăm prin filteredLists pentru a returna listele, pe care apoi le folosim în construirea listei individuale, trecând elementul returnat ca elemente de recuzită componentei List .

Odată terminat, componenta noastră ar trebui să arate astfel, cu liste adăugate:

Componenta de afișare a listei
Liste afișate de componenta `ListDisplay`. (Previzualizare mare)

Următorul este să adăugați componente Listă și TitleInput .

Componenta listă

La fel ca și celelalte componente ale noastre, componenta List va exporta lista ca observator pentru a ajuta magazinul să o urmărească pentru modificări.

 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)

Am folosit bootstrap-ul pentru a crea carduri în primul set de divs -uri și, de asemenea, pentru a alinia pictograma de ștergere pentru a se deplasa spre partea dreaptă a aplicației. În primul rând, am creat o componentă de card pentru a gestiona list noastră și apoi am creat o etichetă de buton pentru button de ștergere care va accepta două obiecte din acesta și va trece o prop la listă, aceasta la clic, va elimina elementul selectat din listă. liste din pagină.

Componenta listei
O singură componentă a listei cu butonul de ștergere. (Previzualizare mare)

Urmează TitleInput , care va conține formularul nostru de introducere pentru adăugarea listelor și titlul proiectului.

TitleInput

Similar celorlalte proiecte ale noastre, vom adăuga o funcție @observer , astfel încât componenta să poată accepta elemente de recuzită din 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)

În primul rând, am inițializat o stare inițială. Folosind React Hooks, am adăugat o stare inițială numită values pe care am stabilit-o la un șir gol. Folosim aceasta pentru a păstra valoarea a ceea ce este introdus în câmpul de intrare. Pentru a afla mai multe despre React Hooks, puteți consulta acest articol de David Abiodun.

Apoi am apelat un obiect pentru adăugarea de liste în magazinul addList și l-am transmis ca elemente de recuzită din magazinul de aplicații.

Apoi am creat o funcție preparedAddList pentru a accepta un obiect eveniment pentru formularele de intrare, am adăugat și un buton pentru adăugarea manuală a listelor la clic.

Aproape gata, trebuie să repornim serverul nostru de proiect rulând:

 yarn start

Și TitleInput -ul nostru ar trebui să arate așa:

O intrare de titlu
Titlu și componentă de intrare. (Previzualizare mare)

Acum am terminat cu toate componentele aplicației noastre, așa că haideți să o asamblam în App.js Pentru a face asta, trebuie să importam componentele titleInput și ListDisplay . De asemenea, trebuie să ne importăm magazinul din componenta Magazin.

Pentru ca MobX să funcționeze în aplicația noastră, trebuie să trecem magazinul MobX ca elemente de recuzită în aplicația noastră și componente individuale, astfel încât acestea să obțină proprietățile și funcțiile din magazin.

 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;

Aplicația noastră ar trebui să arate astfel când este finalizată:

Aplicație de listă finalizată
(Previzualizare mare)

Concluzie

MobX este un excelent manager de stat, în special pentru aplicațiile bazate pe React, construind aplicația noastră de listă, am învățat conceptele de bază ale MobX, stare, derivări și acțiuni. O versiune funcțională a acestei aplicații poate fi găsită aici:

Puteți duce acest lucru mai departe utilizând MobX în următoarea aplicație pe care o creați, care implică gestionarea statului. Mi-ar plăcea să văd cu ce lucruri noi vii. Puteți citi mai multe despre MobX și aplicațiile de management de stat în referințele de mai jos.

Resurse și referințe

  • „React Native with MobX — Noțiuni introductive”, Nader Dabit, Medium
  • „Concepte și principii” MobX (documentație oficială)
  • „Cele mai bune practici cu React Hooks”, Adeneye David Abiodun, Smashing Magazine