Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. React
Code

I componenti funzionali Stateful contro quelli Stateless in React

by
Difficulty:BeginnerLength:LongLanguages:

Italian (Italiano) translation by Cinzia Sgariglia (you can also view the original English article)

React è una popolare libreria di front-end JavaScript per la creazione di interfacce utente interattive. React ha una curva di apprendimento relativamente bassa, che è uno dei motivi perché sta avendo tutta questa attenzione ultimamente.

Anche se ci sono molti concetti importanti da coprire, i componenti sono innegabilmente il cuore e l'anima di React. Avere una buona comprensione dei componenti dovrebbe rendervi la vita facile come sviluppatore di React.

Prerequisiti

Questo tutorial è destinato ai principianti che hanno iniziato a imparare React e hanno bisogno di una migliore panoramica dei componenti. Inizieremo con le basi sui componenti e poi passeremo a concetti più impegnativi quali i pattern dei componenti e quando utilizzare tali pattern. Le classificazioni dei diversi componenti sono state affrontate come classe vs componenti funzionali, componenti stateful vs componenti stateless e contenitore vs componenti di presentational.

Prima di iniziare, voglio presentarvi il frammento di codice che useremo in questo tutorial. È un semplice contatore costruito con React. Mi riallaccerò ad alcune parti di questo esempio nel corso del tutorial.

Quindi, cominciamo.

Cosa sono i componenti?

I componenti sono micro-entità autosufficienti, indipendenti che descrivono una parte dell'interfaccia utente. Un'interfaccia utente di un'applicazione può essere suddivisa in componenti più piccoli, dove ogni componente ha un proprio codice, struttura e API.

Facebook, per esempio, ha migliaia di pezzi di funzionalità interfacciate insieme quando visualizzate la loro applicazione web. Ecco un fatto interessante: Facebook comprende 30.000 componenti, e il numero sta crescendo. L'architettura dei componenti vi consente di pensare a ogni pezzo in maniera isolata. Ogni componente può aggiornare tutto ciò che è alla sua portata senza essere preoccuparsi per come influisca sugli altri componenti.

Se prendiamo come esempio l'interfaccia utente di Facebook, la barra di ricerca sarebbe un buon candidato per un componente. Il newsfeed di Facebook creerebbe un altro componente (o un componente che ospita molti sub-componenti). Tutti i metodi e le chiamate AJAX legate alla barra di ricerca sarebbero all'interno del componente.

I componenti sono riutilizzabili. Se avete bisogno dello stesso componente in più posizioni, è facile. Con l'aiuto della sintassi JSX, potete dichiarare i componenti ovunque volete che vengano visualizzati, e questo è quanto.

Props e State

I componenti necessitano di dati su cui lavorare. Ci sono due modi diversi che è possibile combinare i componenti e i dati: sia props o state. Props e state determinano ciò che esegue il rendering di un componente e come si comporta. Cominciamo con props.

props

Se i componenti erano semplici funzioni di JavaScript, allora props sarebbe l'input della funzione. Andando per analogia, un componente accetta un input (ciò che noi chiamiamo props), lo elabora e quindi esegue il rendering del codice JSX.

Stateful vs Stateless Component Component with props

Anche se i dati di props sono accessibili a un componente, la filosofia di React è che props dovrebbe essere immutabile e top-down. Ciò significa che un componente genitore può passare qualsiasi tipo di dati voglia ai suoi figli come props, ma il componente figlio non può modificare i relativi props. Così, se tentate di modificare i props come ho fatto qui sotto, otterrete il TypeError "Cannot assign to read-only".

State

State, d'altra parte, è un oggetto che è di proprietà del componente dov'è dichiarato. Il suo ambito di applicazione è limitato al componente corrente. Un componente può inizializzare il proprio state e aggiornarlo ogni volta che è necessario. Lo state del componente genitore solito finisce per essere il props del componente figlio. Quando lo state viene passato all'esterno dell'ambito corrente, ci riferiamo ad esso come un prop.

Stateful vs Stateless Component Component with State

Ora che sappiamo le nozioni di base del componente, diamo un'occhiata alla classificazione di base dei componenti.

Componenti di classe vs componenti funzionali

Un componente React può essere di due tipi: un componente di classe o un componente funzionale. La differenza tra i due è evidente dai loro nomi.

Componenti funzionali

I componenti funzionali sono solo funzioni di JavaScript. Essi prendono un input facoltativo che, come ho accennato in precedenza, è ciò che noi chiamiamo props.

Stateful vs Stateless Components Functional Components

Alcuni sviluppatori preferiscono utilizzare le nuove funzioni arrow di ES6 per la definizione dei componenti. Le funzioni arrow sono più compatte e offrono una sintassi concisa per la scrittura di espressioni di funzione. Utilizzando una funzione arrow, possiamo saltare l'uso di due parole chiave, function e return e una coppia di parentesi graffe. Con la nuova sintassi, è possibile definire un componente in una singola riga come questo.

Componenti di classe

I componenti di classe offrono più funzioni e con più funzioni ci sono più bagagli. Il motivo principale per scegliere i componenti di classe sui componenti funzionali è che possono avere state.

La sintassi state = {count: 1} è parte della funzionalità dei campi pubblici della classe. Maggiori informazioni qui sotto.

Ci sono due modi con i quali è possibile creare un componente di classe. Il modo tradizionale è quello di utilizzare React.createClass(). ES6 ha introdotto una sintassi addolcita che consente di scrivere le classi che estendono React.Component. Tuttavia, entrambi i metodi sono destinati a fare la stessa cosa.

I componenti di classe possono esistere anche senza state. Ecco un esempio di un componente di classe che accetta un input props ed esegue il rendering JSX.

Definiamo un metodo costruttore che accetta come input i props. All'interno del costruttore, che chiamiamo super() per passare tutto ciò che viene ereditato dalla classe genitore. Qui ci sono alcuni dettagli che potreste aver perso.

In primo luogo, il costruttore è facoltativo durante la definizione di un componente. Nel caso precedente, il componente non dispone di uno state, e il costruttore non sembra di fare qualcosa di utile. this.props utilizzato all'interno di render() funzionerà indipendentemente dal fatto che il costruttore è definito o meno. Tuttavia, ecco qualcosa dalla documentazione ufficiale:

I componenti di classe devono sempre chiamare il costruttore di base con props.

Come buona pratica, consiglierei di utilizzare il costruttore per tutti i componenti della classe.

In secondo luogo, se utilizzate un costruttore, è necessario chiamare super(). Questo non è un optional, e si otterrà l'errore di sintassi "Missing super() call in constructor" in caso contrario.

E il mio ultimo punto è circa l'uso di super() vs super(props). super(props) deve essere utilizzato se avete intenzione di chiamare this.props all'interno del costruttore. In caso contrario, usare super() da solo è sufficiente.

Componenti Stateful vs componenti Stateless

Questo è un altro modo popolare di classificazione dei componenti. E i criteri per la classificazione sono semplici: i componenti che hanno state e i componenti che non lo hanno.

Componenti Stateful

I componenti Stateful sono sempre componenti di classe. Come accennato in precedenza, i componenti Stateful hanno uno state che viene inizializzato nel costruttore.

Abbiamo creato un oggetto state e lo abbiamo inizializzato con un contatore pari a 0. C'è una sintassi alternativa proposta per rendere questo più facile chiamato class fields. Non si tratta ancora di una parte della specifica ECMAScript, ma se state usando un transpiler di Babel, questa sintassi dovrebbe funzionare fuori dagli schemi.

Potete evitare di utilizzare il costruttore insieme a questa nuova sintassi.

Ora possiamo accedere lo state all'interno dei metodi di classe tra cui render(). Se avete intenzione di utilizzarli all'interno di render() per visualizzare il valore del conteggio corrente, è necessario inserirlo all'interno delle parentesi graffe come segue:

La parola chiave this qui fa riferimento all'istanza del componente corrente.

Inizializzare lo state non è sufficiente, dobbiamo essere in grado di aggiornare lo state al fine di creare un'applicazione interattiva. Se pensavate che questo dovesse funzionare, no, non lo farà.

I componenti React sono dotati di un metodo chiamato setState per l'aggiornamento dello state. setState accetta un oggetto che contiene il nuovo state di count.

Il setState() accetta un oggetto come input e incrementiamo il valore precedente del conteggio di 1, che funziona come previsto. Tuttavia, c'è un problema. Quando ci sono chiamate multiple a setState che leggono un valore dello state precedente e scrivono un nuovo valore in esso, potremmo finire con una condizione competitiva. Ciò significa che i risultati finali non coincideranno con i valori previsti.

Ecco un esempio che dovrebbe rendervelo chiaro. Provate questo nel frammento di codesandbox sopra.

Vogliamo che il setState incrementi il conteggio di 100, quindi lo aggiorni da 1 e quindi rimuova quel 100 che è stato aggiunto in precedenza. Se setState esegue la transizione dello state nell'ordine effettivo, otterremo il comportamento previsto. Tuttavia, setState è asincrono e chiamate multiple a setState potrebbero essere raggruppate per una migliore esperienza dell'interfaccia utente e delle prestazioni. Così il codice precedente produce un comportamento che è diverso da quello che ci aspettiamo.

Pertanto, invece di passare direttamente un oggetto, è possibile passare a una funzione di updater che ha la firma:

prevState è un riferimento allo state precedente ed è garantito per essere sempre aggiornato. props si riferisce ai props del componente, e non abbiamo bisogno di props per aggiornare lo state qui, quindi possiamo ignorarlo. Quindi, possiamo utilizzarlo per l'aggiornamento di state ed evitare la condizione competitiva.

Il setState() rirende il componente, e avete un componente stateful funzionante.

Componenti Stateless

Potete utilizzare una funzione o una classe per la creazione di componenti stateless. Ma a meno che non sia necessario utilizzare un hook lifecycle dei componenti, dovreste andare per i componenti funzionali stateless. Ci sono un sacco di vantaggi se decidete di utilizzare i componenti funzionali stateless qui; sono facili da scrivere, da capire e da testare, e potete evitare la parola chiave this del tutto. Tuttavia, a partire da React v16, non ci sono benefici di prestazioni dall'utilizzo di componenti funzionali stateless sui componenti di classe.

L'unico inconveniente è che si possono avere degli hook lifecycle. Il metodo lifecycle ShouldComponentUpdate() è spesso utilizzato per ottimizzare le prestazioni e per il controllo manuale di cosa ottiene reinterpretato. Non potete utilizzarlo ancora con i componenti funzionali. I refsi, inoltre, non sono neanche supportati.

Componenti container vs componenti presentational

Questo è un altro pattern che è molto utile durante la scrittura dei componenti. Il vantaggio di questo approccio è che la logica di comportamento è separata dalla logica di presentazione.

Componenti presentational

I componenti presentational sono accoppiati con la vista o come appaiono le cose. Questi componenti accettano props dalla loro controparte di contenitore ed eseguono il rendering. Tutto ciò che ha a che fare con la descrizione dell'interfaccia utente dovrebbe andare qui.

I componenti presentational sono riutilizzabili e dovrebbero rimanere disaccoppiati dal livello comportamentale. Un componente di presentazione riceve i dati e i callback esclusivamente tramite props e quando si verifica un evento, come un pulsante che viene premuto, esegue un callback al componente contenitore tramite props per richiamare un metodo di gestione eventi.

I componenti funzionali dovrebbero essere la vostra prima scelta per la scrittura di componenti presentational a meno che uno state sia necessario. Se un componente presentational richiede uno state, esso dovrebbe essere interessato con lo stato di interfaccia utente e non con i dati effettivi. Il componente presentational non interagisce con lo store di Redux o effettua chiamate API.

Componenti container

I componenti del container si occupano della parte comportamentale. Un componente container dice al componente presentational cosa deve essere eseguito facendo uso dei props. Esso non deve contenere markup e stili di DOM limitati. Se state usando Redux, un componente container contiene il codice che invia un'azione allo store. In alternativa, questo è il posto dove dovreste inserire le chiamate API e memorizzare il risultato nello state del componente.

La struttura solita è quella che c'è un componente container nella parte superiore che passa i dati ai suoi componenti presentational figlio come props. Questo funziona per progetti di piccole dimensioni; tuttavia, quando il progetto diventa più grande e avete un sacco di componenti intermedi che semplicemente accettano i props e li trasmettono ai componenti figlio, questo diventerà brutto e difficile da mantenere. Quando accade, è meglio creare un componente container unico per il componente leaf, e ciò faciliterà l'onere sui componenti intermedi.

Quindi che cosa è un PureComponent?

Avrete modo di sentire il termine componente puro molto spesso nelle cerchie di React, e poi c'è React.PureComponent. Quando state imparando React, tutto questo può sembrare un po' confuso. Un componente è detto puro, se è garantito che restituisca lo stesso risultato dato lo stesso props e state. Un componente funzionale è un buon esempio di un componente puro perché, dato un input, sapete che cosa verrà eseguito.

I componenti di classe possono anche essere puri fintanto che i loro props e state non sono modificabili. Se si dispone di un componente con un set 'profondo' immutabile di props e state, l'API di React ha qualcosa chiamato PureComponent. React.PureComponent è simile a React.Component, ma implementa il metodo ShouldComponentUpdate() in modo un po' diverso. ShouldComponentUpdate() viene richiamato prima che qualcosa sia eseguito. Il comportamento predefinito è che restituisce true in modo che qualsiasi modifica a state o ai props riesegua il componente.

Tuttavia, con PureComponent, viene eseguito un confronto superficiale degli oggetti. Il confronto superficiale significa che confrontate i contenuti immediati degli oggetti anziché in modo ricorsivo confrontando tutte le coppie di chiave/valore dell'oggetto. Quindi solo i riferimenti agli oggetti vengono confrontati, e se gli state/props sono mutati, questo potrebbe non funzionare come previsto.

React.PureComponent viene utilizzato per ottimizzare le prestazioni, e non c'è ragione perché si dovrebbe considerare di usarlo a meno che non si verifica una sorta di problema di prestazioni.

Considerazioni finali

I componenti funzionali stateless sono più eleganti e di solito sono una buona scelta per creare i componenti presentational. Perché sono solo funzioni, non avrete difficoltà a scriverli e capirli, e inoltre sono veramente facili da testare.

Dovrebbe essere notato che i componenti funzionali stateless non hanno il sopravvento in termini di ottimizzazione e prestazioni perché non hanno un hook ShouldComponentUpdate(). Questo potrebbe cambiare nelle future versioni di React, dove i componenti funzionali potrebbero essere ottimizzati per migliorare le prestazioni. Tuttavia, se non siete critici delle prestazioni, dovreste attenervi a componenti funzionali per la visualizzazione/presentazione e componenti di classe stateful per il container.

Si spera che questo tutorial vi abbia dato una panoramica generale dell'architettura basata sui componenti e dei diversi pattern dei componenti di React. Cosa ne pensate? Condividetelo nei commenti.

Negli ultimi due anni, React è cresciuto in popolarità. Infatti, abbiamo un numero di elementi nell'Envato Market disponibili per l'acquisto, la revisione, l'implementazione e così via. Se state cercando risorse aggiuntive su React, non esitate a dargli un'occhiata.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.