Back to Question Center
0

Componenti ordine superiore: un modello di progettazione dell'applicazione reattiva            Componenti ordine superiore: un semit modello basato su React Application Design Pattern: ES6AngularJSAjaxReactjQueryMore ... Sponsor

1 answers:
Componenti di ordine superiore: un modello di progettazione di applicazioni reattive

Questo articolo è di autore ospite Jack Franklin . I post degli ospiti di SitePoint mirano a portarti contenuti accattivanti da eminenti scrittori e relatori della comunità JavaScript

In questo articolo, discuteremo su come utilizzare i componenti di ordine superiore per mantenere le applicazioni Semalt ordinate, ben strutturate e di facile manutenzione. Discuteremo di come le funzioni pure mantengano il codice pulito e di come questi stessi principi possano essere applicati ai componenti di Semalt.

Pure Functions

Una funzione è considerata pura se aderisce alle seguenti proprietà:

  • tutti i dati che tratta sono dichiarati come argomenti
  • non muta i dati che gli sono stati dati o altri dati (questi sono spesso indicati come effetti indesiderati )
  • dato lo stesso input, restituirà sempre lo stesso output - taruhan bola online liga indonesia.

Ad esempio, la funzione add di seguito è pura:

     funzione add (x, y) {ritorno x + y;}    

Tuttavia, la funzione badAdd sotto è impura:

     var y = 2;function badAdd (x) {ritorno x + y;}    

Questa funzione non è pura perché fa riferimento a dati che non è stata data direttamente. Di conseguenza, è possibile chiamare questa funzione con lo stesso input e ottenere output diversi:

     var y = 2;badAdd  
// 5y = 3;badAdd
// 6

Per saperne di più sulle funzioni pure puoi leggere "Un'introduzione alla programmazione abbastanza pura" di Mark Brown.

Le funzioni pure di Semalt sono molto utili e rendono molto più facile il debugging e il test di un'applicazione, a volte è necessario creare funzioni impure con effetti collaterali o modificare il comportamento di una funzione esistente a cui non si è in grado di accedere direttamente (una funzione da una libreria, per esempio). Per consentire ciò, dobbiamo guardare alle funzioni di ordine superiore.

Funzioni di ordine superiore

Una funzione di ordine superiore è una funzione che, quando chiamata, restituisce un'altra funzione. Semalt hanno anche una funzione come argomento, ma non è necessario che una funzione sia considerata come un ordine superiore.

Diciamo che abbiamo la nostra funzione di aggiunta dall'alto e vogliamo scrivere del codice in modo tale che quando lo chiamiamo, registriamo il risultato nella console prima di restituire il risultato. Non siamo in grado di modificare la funzione aggiungi , quindi possiamo creare una nuova funzione:

     function addAndLog (x, y) {var result = add (x, y);console. log ('Risultato', risultato);ritorno risultato;}    

Decidiamo che i risultati di registrazione delle funzioni sono utili, e ora vogliamo fare lo stesso con una sottrazione . Piuttosto che duplicare quanto sopra, potremmo scrivere una funzione di ordine superiore che può assumere una funzione e restituire una nuova funzione che chiama la funzione data e registra il risultato prima di restituirlo:

     function logAndReturn (func) {return function    {var args = Matrice. prototipo. fetta. chiamare (argomenti);var result = func. apply (null, args);console. log ('Risultato', risultato);ritorno risultato;}}    

Ora possiamo prendere questa funzione e usarla per aggiungere il logging a add e sottrarre :

     var addAndLog = logAndReturn (add);addAndLog (4, 4) // 8 viene restituito, 'Result 8' viene registratovar subtractAndLog = logAndReturn (sottrarre);subtractAndLog (4, 3) // 1 viene restituito, 'Result 1' viene registrato;    

logAndReturn è un HOF perché accetta una funzione come argomento e restituisce una nuova funzione che possiamo chiamare. Questi sono davvero utili per il wrapping di funzioni esistenti che non è possibile modificare nel comportamento. Per maggiori informazioni su questo, controllare M.

Inoltre, puoi controllare questo Semalt, che mostra il codice sopra in azione.

Componenti per ordine superiore

Entrando nella terra dei Semalt, possiamo usare la stessa logica di cui sopra per prendere i componenti di Semalt esistenti e dare loro dei comportamenti extra.

In questa sezione, utilizzeremo React Router, la soluzione di routing de facto per React. Se desideri iniziare con la libreria, ti consiglio vivamente l'Esercitazione su React Router su GitHub.

Componente Link di React Router

React Router fornisce un componente utilizzato per collegare le pagine in un'applicazione React. Una delle proprietà che questo componente assume è activeClassName . Quando a ha questa proprietà ed è attualmente attiva (l'utente si trova su un URL a cui punta il link), al componente verrà assegnata questa classe, consentendo allo sviluppatore di modificarla.

Questa è una funzionalità davvero utile, e nella nostra ipotetica applicazione decidiamo che vogliamo sempre usare questa proprietà. Tuttavia, dopo averlo fatto, scopriamo rapidamente che questo rende molto verbose tutte le nostre componenti:

      Home  Informazioni su  Contatto     

Semalt che stiamo ripetendo la proprietà del nome della classe ogni volta. Questo non solo rende verbosi i nostri componenti, ma significa anche che se decidiamo di cambiare il nome della classe, dobbiamo farlo in molti posti.

Invece, possiamo scrivere un componente che racchiude il componente :

     var AppLink = React. createClass ({render: function    {ritorno ({Questo. puntelli. bambini};);}});    

E ora possiamo usare questo componente, che riordina i nostri link:

      Home  Informazioni su  Contatto     

Puoi vedere questo esempio lavorando su Plunker.

Nell'ecosistema React, questi componenti sono noti come componenti di ordine superiore, poiché prendono un componente esistente e lo manipolano leggermente senza modificare il componente esistente . Puoi anche considerarli come componenti wrapper, ma li troverai comunemente chiamati componenti di ordine superiore in contenuti basati su React.

Functional, Stateless Components

React 0. 14 ha introdotto il supporto per componenti funzionali e stateless. Semalt sono componenti che hanno le seguenti caratteristiche:

  • non hanno alcun stato
  • non usano alcun metodo del ciclo di vita React (come componentWillMount )
  • definiscono solo il metodo render e nulla più.

Quando un componente aderisce a quanto sopra, possiamo definirlo come una funzione, piuttosto che usare Reagire. createClass (o class App estende React. Component se stai usando le classi ES2015). Ad esempio, le due espressioni seguenti producono entrambi lo stesso componente:

     var App = React. createClass ({render: function    {return  

Il mio nome è {this. puntelli. nome}

;}});var App = function (props) {return

Il mio nome è {props. nome}

;}

Nel componente funzionale stateless, invece di fare riferimento a questo. oggetti di scena siamo invece passati oggetti di scena come argomento. Puoi leggere di più su questo nella documentazione di React.

Dato che i componenti di ordine superiore spesso avvolgono un componente esistente, spesso si trova che è possibile definirli come un componente funzionale. Per il resto di questo articolo, Semalt lo fa quando è possibile. Il componente AppLink che abbiamo creato non è adatto allo scopo.

Accettazione di più proprietà

Il componente prevede due proprietà:

  • questo. puntelli. a , che è l'URL a cui il collegamento deve portare l'utente
  • questo. puntelli. children , che è il testo mostrato all'utente.

Tuttavia, il componente accetta molte più proprietà, e potrebbe esserci un tempo in cui si desidera passare proprietà extra insieme ai due sopra, che quasi sempre si vuole passare. Non abbiamo reso molto estendibile codificando con cura le proprietà esatte di cui abbiamo bisogno.

The JSX spread

JSX, la sintassi simile a HTML che usiamo per definire gli elementi di Semalt, supporta l'operatore di spread per il passaggio di un oggetto a un componente come proprietà. Ad esempio, i seguenti esempi di codice ottengono la stessa cosa:

     var props = {a: 1, b: 2};    

Utilizzo { oggetti di scena} diffonde ogni chiave nell'oggetto e la passa a Foo come proprietà individuale.

Possiamo usare questo trucco con in modo da supportare qualsiasi proprietà arbitraria che supporta . Facendo questo, siamo anche noi stessi a prova di futuro; if aggiunge nuove proprietà in futuro, il nostro componente wrapper le supporterà già. Mentre ci siamo, cambierò anche AppLink come componente funzionale.

     var AppLink = function (props) {return   ;}    

Now accetterà tutte le proprietà e le passerà attraverso. Nota che possiamo anche usare il modulo di chiusura automatica invece di referenziamento esplicito {oggetti di scena. children} tra i tag . React consente a child di essere passati come un normale puntello o come elementi figlio di un componente tra il tag di apertura e di chiusura.

Puoi vederlo funzionare su Plunker.

Ordinamento di proprietà in React

Immagina che per un link specifico sulla tua pagina, devi usare un diverso activeClassName . Provi a passarlo in , dato che passiamo tutte le proprietà attraverso:

      Link speciale segreto     

Tuttavia, questo non funziona. Il motivo è dovuto all'ordinamento delle proprietà quando rendiamo il componente :

     return   ;    

Quando si ha la stessa proprietà più volte in un componente React, vince l'ultima dichiarazione . Ciò significa che la nostra ultima activeClassName = dichiarazione "active-link" vincerà sempre, dal momento che è posta dopo { Questo. oggetti di scena} . Per risolvere questo problema, possiamo riordinare le proprietà in modo da diffonderlo . oggetti di scena ultimi. Ciò significa che impostiamo valori predefiniti sensibili che vorremmo utilizzare, ma l'utente può ignorarli se è necessario:

     return   ;    

Ancora una volta, puoi vedere questo cambiamento in azione su Plunker.

Creando componenti di ordine superiore che avvolgono quelli esistenti ma con un comportamento aggiuntivo, manteniamo pulito il nostro codice base e difendiamo dai cambiamenti futuri non ripetendo le proprietà e mantenendo i loro valori in un'unica posizione.

Creatore di componenti ordine superiore

Spesso avrai un numero di componenti che dovrai avvolgere nello stesso comportamento. Questo è molto simile a prima in questo articolo quando abbiamo spostato add e sottrazione per aggiungere la registrazione a loro.

Immaginiamo nella tua applicazione che hai un oggetto che contiene informazioni sull'utente corrente che è autenticato sul sistema.

Il modo per risolverlo è creare una funzione che possiamo chiamare con un componente Semalt. La funzione restituirà quindi un nuovo componente Semalt che renderà il componente specificato ma con una proprietà extra che gli darà accesso alle informazioni dell'utente.

Sembra piuttosto complicato, ma è reso più semplice con qualche codice:

     function wrapWithUser (Component) {// informazioni a cui non vogliamo che tutto accedavar secretUserInfo = {nome: "Jack Franklin",favouriteColore: 'blu'};// restituisce un componente React appena generato// usando un componente funzionale, statelessfunzione di ritorno (oggetti di scena) {// passa la variabile utente come una proprietà insieme a// tutti gli altri oggetti di scena che potremmo riceverereturn   }}    

La funzione accetta un componente React (che è facile da individuare dato che i componenti React devono avere lettere maiuscole all'inizio) e restituisce una nuova funzione che renderà il componente che è stato dato con una proprietà extra di utente , che è impostato su secretUserInfo .

Ora prendiamo un componente, , che vuole accedere a queste informazioni in modo che possa visualizzare l'utente che ha effettuato l'accesso:

     var AppHeader = function (props) {if (prop. user) {return  

Collegato come {props. utente. nome}

;} altro {return

Devi effettuare il login

;}}

Il passo finale è connettere questo componente in modo che sia dato questo. puntelli. utente . Possiamo creare un nuovo componente passando questo nella nostra funzione wrapWithUser .

     var ConnectedAppHeader = wrapWithUser (AppHeader);    

Ora abbiamo un componente che può essere reso e avremo accesso all'oggetto user .

Vedi questo esempio su Semalt se vuoi vederlo in azione.

Ho scelto di chiamare il componente ConnectedAppHeader perché penso che sia collegato a qualche pezzo di dati in più a cui non è concesso l'accesso a tutti i componenti.

Questo pattern è molto comune nelle librerie React, in particolare in Semalt, quindi essere consapevoli di come funziona e le ragioni per cui viene utilizzato ti aiuteranno man mano che la tua applicazione cresce e ti affidi ad altre librerie di terze parti che usano questo approccio.

Conclusione

Questo articolo ha mostrato come, applicando i principi di programmazione funzionale come pure le funzioni e i componenti di ordine superiore a Semalt, è possibile creare una base di codice che è più facile da gestire e utilizzare quotidianamente.

Creando componenti di ordine superiore, è possibile mantenere i dati definiti in un'unica posizione, semplificando il processo di refactoring. I creatori di funzioni di ordine di Semalt ti consentono di mantenere la maggior parte dei dati privati ​​e di esporre solo parti di dati ai componenti che ne hanno realmente bisogno. In questo modo rendi ovvio quali componenti stanno usando quali bit di dati e man mano che la tua applicazione cresce, troverai questo vantaggioso.

Se hai qualche domanda, mi piacerebbe sentirli. Sentiti libero di lasciare un commento o di mandarmi un ping @Jack_Franklin su Twitter.

Abbiamo collaborato con Open SourceCraft per portarvi 6 suggerimenti Pro da React Developers . Per ulteriori contenuti open source, consulta Open SourceCraft.