In questo articolo, vi spiegherò come applicare il pattern dependencies Injection nel vostro progetto React, con l’aiuto di Mobx e Mobx-react e della funzione/decoratore Inject.

L’obbiettivo di questo pattern è permettervi di riusare la stessa istanza di servizio all’interno di molte classi e/o funzioni

Se non avete ancora inizializzato il vostro progetto React Typescript, potete farlo rapidamente usando il comando:

In pochi istanti il necessario per iniziare sarà pronto, poi installiamo mobx e mobx-react.

Il pattern dependencies injection normalmente consente di iniettare un servizio all’interno di una classe, nel caso di React, i suoi componenti non son più classi nelle ultime release, ma funzioni.

Quindi andremo a iniettare dei servizi (o globali) in delle funzioni tramite un <Provider />, che ci consentirà di richiamarli indipendentemente dal grado di parentela del nostro componente, purché sia un figlio o nipote del componente di mobx-react: <Provider />.

Ecco un esempio di servizio, che fa dei calcoli, nello specifico, la funzione sum di myService, somma tutti gli argomenti che gli vengono passati.

Come vi accennavo sopra, per poter procedere con l’iniezione nei componenti, questi devono essere figli o nipoti del componente mobx-react <Provider />, vi riporto l’esempio:

Nel codice qui sopra, potete vedere che ho creato una semplice lista di servizi (serviceList) che vado poi a passare destrutturata al <Provider>.


Potrò poi andare a recuperare il myService dentro il mio componente Example, utilizzando la funzione (o decoratore) “inject” di mobx-react.

Nel blocco di codice qui sopra, ho specificato che voglio andare a recuperare solo il servizio myService, in quanto potrei avere ipoteticamente “N” servizi passati nel <Provider />.


Potrò comodamente recuperare il mio servizio tra gli argomenti (props) del mio componente.


Vi consiglio nell’interfaccia di specificare che si tratta di un servizio, identificandolo come readonly e di metterlo potenzialmente non definito.

Approfondimenti

Uno dei vantaggi principali di questo pattern, è di poter utilizzare sempre le stesse istanze dei servizi in ogni componente necessario, senza doverne creare in più punti.

Un vantaggio non da poco, è anche di centralizzare i test sui servizi.

Questo ci consente di evitare di riscrivere e inizializzare delle classi con i medesimi costruttori in diversi punti del codice, risparmiandoci verbosità e memoria.

Servizi Asincroni

In alcuni casi, dei servizi per essere inizializzati dovranno compiere operazioni asincrone (come caricare dei json), questi vanno passati al <Provider /> solo nel momento in cui sono effettivamente utilizzabili.


Questa operazione può essere fatta utilizzando lo stato derivato e ridisegnano l’app, oppure si può attendere ad instanziare React dopo l’inizializzazione dei servizi.

Personalmente preferisco avviare subito React, per renderizzare un minimo di UX (esempio header, footer e spinner), poi con un hook (esempio: useState) ridisegnare il <Provider /> con la nuova lista di servizi.

Un Importante accortezza, è che non potrete cambiare la struttura iniziale dei servizi passata al <Provider />, ma solo quella dei suoi figli, mi spiego meglio:

(es. in cui il padre è “service” e i figli “child”)

<Provider padre={ figlio: value }>

Potrete andare a valorizzare i figli come preferite, ma non aggiungere altri padri a seguito il primo render.

<Provider service={child: value, child:1 value} />

Detto questo, possiamo ovviare a questo problema, andando ad aggiungere un livello alla profondità all’oggetto che passiamo al <Provider  /> con l’elenco dei servizi:

{
    service: { myService: myService}
}

Potete vedere come segue, che con l’utilizzo degli Hook, vado a ridisegnare il componente <Provider /> e tutti i suoi figli, rispettando le chiavi del padre (service), ma cambiando i figli.

Ora andremo a prendere da dentro il nostro componente <Example /> le injection come segue:

A questo punto, avremo la possibilità di attingere sia i servizi di partenza, che quelli aggiunti successivamente direttamente da dentro i nostri componenti.



Leave a Reply

Your email address will not be published.