Utilizzo di Mobx come gestore di stato nelle applicazioni native di React

Pubblicato: 2022-03-10
Riassunto veloce ↬ MobX è uno dei tanti strumenti di gestione dello stato disponibili per gli sviluppatori React. In questo tutorial, Fortune Kay spiega cos'è MobX e come puoi usarlo nelle tue applicazioni React creandone una da zero.

La gestione dello stato è parte integrante dello sviluppo di applicazioni JavaScript, in particolare le applicazioni React e React Native. In questo tutorial impareremo come utilizzare la libreria MobX per la gestione dello stato; comprendere i concetti fondamentali, alcuni casi d'uso e creare un semplice esempio.

Nota: la conoscenza di base di Javascript e React Native sarà di grande beneficio mentre si lavora con questo tutorial.

Utilizzo di MobX nelle applicazioni React

Lo stato è i dati con cui stanno lavorando i tuoi componenti: contiene i dati richiesti da un componente e determina ciò che un componente esegue il rendering. La gestione dello stato è il processo di gestione del modo in cui lo stato viene aggiornato e passato da un componente all'altro. Il monitoraggio e l'utilizzo dei dati in un'applicazione possono essere difficili e questa è la necessità di biblioteche di gestione dello stato. Gestire tutti i dati per la tua applicazione può essere un po' scoraggiante, specialmente quando la tua applicazione cresce in termini di dimensioni e complessità, creare il tuo strumento di gestione dello stato non è solo dispendioso in termini di tempo ma è difficile, ecco perché potresti voler utilizzare una libreria di gestione dello stato.

Tuttavia, è importante sapere che lo stato non è l'unico dato che un componente esegue il rendering, i componenti possono anche eseguire il rendering degli oggetti di scena passati ad esso.

Opzioni per la gestione dello stato

Le librerie di gestione dello stato per le applicazioni React Native includono; Reagire Context API, Redux, MobX e Unstateted Next.

Sebbene questi gestori di stato abbiano ciascuno i loro vantaggi e svantaggi, personalmente raccomando MobX per la sua semplicità, il codice standard minimo: non richiede la modifica del codice, questo perché nel suo nucleo, MobX è e sembra JavaScript; non è necessario un cambio di architettura per supportarlo (a differenza di Redux e, in misura minore, Context).

In effetti è un'astrazione così invisibile che in molti casi se elimini tutto il codice MobX - i decoratori @observable , @computed , @action e osservatore , il tuo codice funzionerà esattamente allo stesso modo (anche se avrà alcuni problemi di prestazioni ) e non è limitato a uno stato globale. Questi sono alcuni motivi per andare avanti con MobX come gestore di stato preferito per le tue applicazioni React Native.

Sebbene sia anche importante notare alcuni problemi con l'utilizzo di MobX come gestore di stato, alcuni dei quali includono l'evitare le regole su come implementarlo e MobX può essere difficile da eseguire il debug soprattutto quando si cambia stato direttamente in un componente senza utilizzare le @actions parametro.

Cos'è MobX?

Secondo la documentazione ufficiale, MobX è una libreria testata in battaglia che rende la gestione dello stato semplice e scalabile applicando in modo trasparente la programmazione reattiva funzionale. MobX tratta la tua applicazione come un foglio di calcolo. La logica è che tutto ciò che può essere derivato dallo stato dell'applicazione, dovrebbe essere eseguito automaticamente .

Architettura di stato MobX
Architettura di stato MobX. (Grande anteprima)
Altro dopo il salto! Continua a leggere sotto ↓

Principi fondamentali e concetto di MobX

MobX si differenzia dagli altri gestori statali con i seguenti concetti.

1. Stato

Lo stato è il dato che contiene la tua applicazione: è all'incirca l'intero contenuto della sua memoria. Questo vale anche per i tuoi componenti.

2. Derivazioni

In MobX, tutto ciò che può essere derivato dallo stato senza interazioni è una derivazione. Esempi di derivazioni includono:

  • Interfaccia utente,
  • Componenti aggiuntivi di back-end come modifiche a un server.

MobX ha due tipi principali di derivazioni:

  • Valori calcolati
    I valori calcolati sono per lo più valori che possono essere derivati ​​da uno stato corrente utilizzando funzioni pure.
  • Reazioni
    Le reazioni nelle derivazioni sono effetti collaterali che si verificano a seguito di modifiche nello stato dell'applicazione. Sono simili a un valore calcolato, ma invece di produrre un nuovo valore, una reazione produce un effetto collaterale per cose come la stampa sulla console, l'esecuzione di richieste di rete, l'aggiornamento incrementale dell'albero dei componenti di React per applicare patch al DOM e così via.

Una regola d'oro quando si utilizza MobX è che quando si crea un valore basato sullo stato corrente, utilizzare un valore calcolato.

3. Azioni

A differenza delle derivazioni, le azioni sono codice che causano modifiche allo stato di un'applicazione, codice che modifica lo stato. Sono tutto ciò che modifica lo stato. Con MobX puoi renderlo esplicito nel tuo codice, le azioni sono principalmente eventi utente come input, push di dati di back-end o persino eventi programmati.

Per comprendere meglio Actions, diamo un'occhiata a un esempio dalla documentazione di MobX.

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

Qui, impostiamo un tick @observable con un valore iniziale di 0. Successivamente, abbiamo creato una funzione di incremento che è anche un'azione che aggiorna il valore iniziale una volta che viene eseguito un tick ogni secondo.

Osservabili in MobX

I valori osservabili o osservabili in MobX sono principalmente primitive JavaScript, oggetti semplici, classi, array e mappe. Vengono utilizzati principalmente dichiarando prima un osservabile e aggiungendo un valore ad esso e quindi chiamandolo aggiungendo un @osservabile come mostrato di seguito:

 observable(value) @observable classProperty = value

Approccio all'architettura del negozio in MobX

L'architettura principale di MobX include parti e idee come servizi, negozio, modelli di visualizzazione e contenitori, alcuni dei quali sono spiegati di seguito.

  • Servizio
    Di solito è una funzione chiamata da un contenitore; possono essere utilizzati per ottenere dati dalle API ed essere aggiunti allo store.
  • Negozio
    Come suggerisce il nome, questo è il luogo centrale dello stato utilizzato da un'applicazione. Di solito in MobX, questi includono osservabili, variabili, azioni e proprietà calcolate.
  • Contenitore
    Questo chiama il service e inserisce i dati da View Model a View Component come oggetti di scena React (dovrebbe essere contrassegnato con @observer decorator).

MobX in applicazioni React e Native

A scopo di apprendimento, in questo tutorial creeremo una semplice app elenco che consentirà a un utente di aggiungere, visualizzare ed eliminare elementi di elenco. Utilizzeremo MobX come gestore di stato in questa applicazione per aggiungere elenchi, aggiornarli ed eliminarli dallo stato dell'app. Tuttavia, è importante notare che hai già compreso i concetti di base di JavaScript e React.

Senza ulteriori indugi, iniziamo!

Configurare il tuo ambiente

Ora che sappiamo cos'è MobX e come funziona, lascia che ti guidi attraverso l'impostazione del tuo progetto.

Innanzitutto, creiamo un progetto con quanto segue, scrivi il seguente codice sul tuo terminale per inizializzare un progetto:

 npx create-react-app listapp

Il codice precedente creerà un'applicazione React nuda utilizzando il pacchetto create-react-app. Sposta nella directory del progetto:

 cd listapp

Per questa app, avremo bisogno di tre componenti:

  • TitleInput
    Questo conterrà il titolo del nostro progetto e un modulo di input per l'aggiunta di elenchi.
  • List
    Questo sarà un modulo di input che consentirebbe a un utente di aggiungere un elenco. Avrà un pulsante Aggiungi per aggiungere gli elementi della nostra lista.
  • ListsDisplay
    Questo componente visualizzerà tutti gli elementi dell'elenco utente e anche un pulsante di eliminazione che viene generato automaticamente quando un utente aggiunge un elemento dell'elenco.

Useremo un Store.js per contenere lo stato dell'app e i metodi per modificarlo in modo simile a Redux. Descriviamo a cosa serviranno.

  • mobx
    Questo è il manager statale che useremo per questo progetto.
  • mobx-react
    Questo è il binding ufficiale React per MobX.
  • bootstrap
    Useremo bootstrap versione 4.5 per dare uno stile al nostro progetto.
  • uuid
    Viene utilizzato per creare automaticamente le chiavi per l'eliminazione degli elenchi.

Fatto ciò, andiamo avanti e installiamo questi pacchetti. Li installerò con un'alternativa npm fatta in filato:

 yarn add mobx mobx-react [email protected] uuid

Una volta installati i pacchetti, avvieremo la nostra app in modalità sviluppo eseguendo il codice seguente nel nostro terminale:

 yarn start

Configurazione del nostro App Store

Creiamo un negozio per il nostro progetto. Innanzitutto, crea un file nella directory principale del nostro progetto chiamato ListStore , questa sarà la posizione centrale dello stato della nostra app.

Per questa app, dovremo creare un ListStore per non ripeterci quando lo utilizziamo in altri componenti dell'app.

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

Nel codice sopra, abbiamo importato tre funzioni da mobx .

  • observable
    Contiene una variabile che può essere aggiornata in caso di cambio di stato.
  • action
    Utilizzato per modificare lo stato dell'applicazione.
  • computed
    Valori che possono essere derivati ​​dallo stato esistente o da altri valori calcolati, cambia dopo la modifica di uno stato.

La classe List ha due valori oggetto che sono done e value che manterrà lo stato iniziale dell'app e la modifica in caso di modifiche.

Vogliamo che il nostro nuovo elenco crei automaticamente una chiave in modo da poter ottenere automaticamente un pulsante di eliminazione una volta creato un elenco, qui uuid viene utilizzato per creare automaticamente chiavi nella nostra applicazione.

Successivamente, abbiamo aggiunto una funzione addList che aggiungerà elenchi quando si fa clic utilizzando il metodo .push() per eseguire il push dell'elenco nell'array che abbiamo già creato nell'array @observable lists .

La funzione deleteList accetta List come una proprietà che dovrebbe essere l'elemento che l'utente desidera rimuovere. Quindi impostiamo il valore di this.Lists su un nuovo array dopo aver rimosso l'elemento selezionato.

Sia addLists che deleteList sono azioni perché modificano lo stato della nostra app quando vengono apportate modifiche.

Inizializzazione del MobX Store

Il prossimo passo nella nostra lista è importare il nostro negozio nel nostro App.js e usarlo nel nostro progetto.

 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;

Qui abbiamo importato i componenti TitleInput e ListDisplay . Quindi abbiamo inizializzato lo store nel nostro App.js per poterlo passare come prop ai componenti TitleInput e ListDisplay .

Normalmente questo genererà un errore perché non abbiamo lavorato sugli altri componenti, quindi facciamolo. Costruiamo il componente ListDisplay .

ListDisplay

Questo componente mostra tutti i nostri elenchi aggiunti e genera anche automaticamente un pulsante di eliminazione una volta aggiunto un nuovo elenco.

 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)

Per questo componente, abbiamo creato una funzione ListDisplay e l'abbiamo resa un osservatore, abbiamo anche destrutturato le funzioni list e deletelist dal negozio, in questo modo abbiamo semplificato il passaggio come oggetti di scena.

Successivamente, eseguiamo il mapping tramite filteredLists per restituire le liste, che poi utilizziamo nella creazione della singola lista passando l'elemento restituito come prop al componente List .

Una volta terminato, il nostro componente dovrebbe apparire così con gli elenchi aggiunti:

Il componente di visualizzazione dell'elenco
Elenchi visualizzati dal componente `ListDisplay`. (Grande anteprima)

Il prossimo è aggiungere un List e un TitleInput componenti.

Componente elenco

Proprio come gli altri nostri componenti, il nostro componente List esporterà l'elenco come osservatore per aiutare il negozio a controllarlo per le modifiche.

 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)

Ho usato il bootstrap per creare carte nel primo set di divs e ho anche allineato l'icona di eliminazione per spostarmi verso il lato destro dell'app. In primo luogo, abbiamo creato un componente della scheda per gestire la nostra list e quindi abbiamo creato un tag pulsante per il button di eliminazione che accetterà due oggetti di questo e passerà un oggetto di scena alla lista, questo al clic rimuoverà la voce della lista selezionata dalla elenchi nella pagina.

Il componente elenco
Un singolo componente dell'elenco con il pulsante Elimina. (Grande anteprima)

Il prossimo è il nostro TitleInput che conterrà il nostro modulo di input per l'aggiunta di elenchi e il titolo per il progetto.

TitleInput

Simile agli altri nostri progetti, aggiungeremo una funzione @observer in modo che il componente possa accettare oggetti di scena dall'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)

Innanzitutto, abbiamo inizializzato uno stato iniziale. Usando React Hooks, abbiamo aggiunto uno stato iniziale chiamato values che impostiamo su una stringa vuota. Lo usiamo per contenere il valore di ciò che viene inserito nel campo di input. Per saperne di più su React Hooks, puoi consultare questo articolo di David Abiodun.

Quindi abbiamo chiamato un oggetto per aggiungere elenchi allo store addList e lo abbiamo passato come prop dall'app store.

Successivamente abbiamo creato una funzione preparedAddList per accettare un oggetto evento per i moduli di input, abbiamo anche aggiunto un pulsante per aggiungere manualmente gli elenchi al clic.

Quasi finito, dobbiamo riavviare il nostro server di progetto eseguendo:

 yarn start

E il nostro TitleInput dovrebbe assomigliare a questo:

Un titolo di input
Titolo e componente di input. (Grande anteprima)

Ora abbiamo finito con tutti i componenti dell'app, quindi assembliamolo nel nostro App.js . Per farlo, dobbiamo importare i nostri componenti titleInput e ListDisplay . Abbiamo anche bisogno di importare il nostro negozio dal componente Store.

Affinché MobX funzioni nella nostra app, dobbiamo passare il negozio MobX come oggetti di scena nella nostra app e singoli componenti in modo che ottengano le proprietà e le funzioni nel negozio.

 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;

La nostra app dovrebbe apparire così una volta completata:

Elenco completo app
(Grande anteprima)

Conclusione

MobX è un ottimo gestore di stato soprattutto per le applicazioni basate su React, costruendo la nostra app elenco, abbiamo appreso i concetti di base di MobX, stato, derivazioni e azioni. Una versione funzionante di questa app può essere trovata qui:

Puoi andare oltre usando MobX nella prossima applicazione che crei che coinvolge la gestione dello stato. Mi piacerebbe vedere quali novità ti vengono in mente. Puoi leggere di più su MobX e sulle applicazioni di gestione dello stato nei riferimenti seguenti.

Risorse e riferimenti

  • "React Native con MobX: per iniziare", Nader Dabit, Medium
  • “Concetti e principi” MobX (documentazione ufficiale)
  • "Migliori pratiche con React Hooks", Adeneye David Abiodun, Smashing Magazine