Introduzione agli Hooks
Gli Hooks sono stati aggiunti in React 16.8. Ti permettono di utilizzare state
ed altre funzioni di React senza dover scrivere una classe.
import React, { useState } from 'react';
function Esempio() {
// Dichiara una nuova variable di stato, che chiameremo "contatore" const [contatore, setContatore] = useState(0);
return (
<div>
<p>Hai cliccato {contatore} volte</p>
<button onClick={() => setContatore(contatore + 1)}>
Cliccami
</button>
</div>
);
}
Questa nuova funzione useState
è il primo “Hook” che impareremo, l’esempio appena visto è solo un assaggio. Non preoccuparti se ti pare non abbia molto senso per il momento!
Puoi incominciare a saperne di più riguardo agli Hooks nella pagina successiva. In questa pagina, continueremo a spiegare perché abbiamo introdotto gli Hooks in React e come possono aiutarti a sviluppare ottime applicazioni.
Nota
React 16.8.0 è la prima versione che supporta gli Hooks. Durante l’upgrade, non dimenticare di aggiornare tutti i pacchetti, incluso React DOM. React Native supporta gli Hooks a partire dalla release 0.59 di React Native.
Introduzione Video
Durante React Conf 2018, Sophie Alpert e Dan Abramov hanno introdotto gli Hooks, seguiti da Ryan Florence che ha dimostrato come rifattorizzare una applicazione utilizzandoli. Eccoti il video:
Retrocompatibili
Prima di continuare, ricorda che gli Hooks sono:
- Completamente facoltativi. Puoi provare ad usare gli Hooks in pochi componenti senza dover riscrivere alcun codice esistente. Non devi per forza imparare o utilizzare gli Hooks adesso se non ti va.
- 100% retrocompatibili. Gli Hooks non contengono alcun cambiamento che possa rompere funzionalità esistenti.
- Disponibili ora. Gli Hooks sono disponibili a partire dalla release v16.8.0.
Non esiste alcun piano per la rimozione delle classi da React. Puoi leggere di più riguardo alla strategia di adozione graduale degli Hooks nella sezione in basso in questa pagina.
Gli Hooks non cambiano la tua conoscenza dei concetti di React. Invece, gli Hooks offrono un accesso più diretto alle API dei concetti React che conosci già: props, state, context, refs, e lifecycle. Come mostreremo di seguito, gli Hooks offrono anche un nuovo potente modo per combinarli.
Se ti interessa soltanto imparare gli Hooks, puoi passare direttamente all pagina successiva! Continua a leggere se invece vuoi saperne di più riguardo alle motivazioni dietro l’introduzione degli Hooks, oltre a capire come possiamo cominciare ad utilizzarli senza dover riscrivere le nostre applicazioni.
Motivazioni
Gli Hooks risolvono un’ampia varietà di problemi che sembrano disconnessi tra loro in React. Problemi che abbiamo incontrato in oltre cinque anni di scrittura e manutenzione di decine di migliaia di componenti. Se stai imparando React, se lo usi quotidianamente o anche se preferisci una libreria diversa che ha un modello simile basato sui componenti, riconoscerai alcuni di questi problemi.
È difficile riutilizzare logica dipendente dallo stato in componenti diversi
React non offre un modo per “collegare” comportamenti riutilizzabili ad un componente (per esempio, connetterlo ad uno store). Se hai acquisito un po’ di esperienza in React, sarai a conoscenza di concetti come render props e componenti di ordine superiore che provano a risolvere questo problema. Tuttavia, questi patterns ti richiedono di ristrutturare i tuoi componenti quando vuoi utilizzarli, il che può essere difficile oltre a rendere il codice più difficile da seguire. Se osservi una tipica applicazione React usando React DevTools, noterai molto probabilmente un “wrapper hell” di componenti circondato da livelli di providers, consumers, componenti di ordine superiore, render props, ed altre astrazioni. Anche se possiamo filtrarli in DevTools, il problema principale resta: React ha bisogno di una migliore primitiva per condividere logica basata sullo stato (stateful).
Con gli Hooks, puoi estrarre logica stateful da un componente così da renderla testabile in modo indipendente e riutilizzabile. Gli Hooks ti permettono di riutilizzare logica stateful senza dover cambiare la tua gerarchia dei componenti. Ciò rende facile la condivisione degli Hooks tra vari componenti o con la comunità.
Ne discuteremo più in dettaglio nella sezione Hooks Personalizzati.
Componenti complessi diventano difficili da capire
Ci siamo ritrovati più volte a dover mantenere componenti che sono passati dall’essere semplici fino a crescere in un groviglio di logica stateful ed effetti collaterali. Ogni metodo di lifecycle spesso contiene un mix di logica non correlata. Per esempio, i componenti potrebbero richiamare dati da qualche API in componentDidMount
e componentDidUpdate
. Comunque, lo stesso metodo componentDidMount
può contenere anche logica per l’impostazione di event listeners, con le relative operazioni di pulizia eseguite in componentWillUnmount
. Parti di codice correlate e che generalmente cambiano allo stesso tempo finiscono per essere divise perché abbiamo codice completamente non correlato all’interno dello stesso metodo. Ciò rende troppo semplice l’introduzione di bugs ed inconsistenze.
In molti casi non è possibile suddividere questi componenti in altri più piccoli in quanto la logica stateful è dappertutto. È difficile anche testare questi componenti. Ecco perché molti preferiscono utilizzare una libreria di gestione dello stato separata. Comunque, ciò spesso introduce troppa astrazione, richiede di saltare da un file all’altro frequentemente e rende la riutilizzazione dei componenti più difficile.
Per risolvere questo problema, gli Hooks ti permettono di dividere un componente in funzioni più piccole basate sui pezzi che sono correlati (quali una sottoscrizione ad un particolare evento o la richiesta di dati), piuttosto che forzare una suddivisione basata sui metodi di lifecycle. Puoi anche decidere di gestire lo stato del tuo componente con un reducer per renderlo più prevedibile.
Ne parleremo più in dettaglio nella sezione Usare l’Hook Effect.
Le classi confondono sia le persone che le macchine
Oltre a rendere il riutilizzo del codice e la sua organizzazione più difficile, abbiamo notato che le classi costituiscono una grande barriera per l’apprendimento di React. Devi sapere come this
funziona in JavaScript, il che è molto diverso da come funziona nella maggioranza dei linguaggi. Senza l’utilizzo di ES2022 public class fields, il codice è molto verboso. Le persone possono capire perfettamente le props, lo state ed il flusso dati top-down, ma ritrovarsi ad avere difficoltà con le classi. La distinzione tra funzioni e componenti classe in React e quando usare l’una o l’altra alternativa causa spesso disaccordi anche tra gli sviluppatori React più esperti.
Inoltre, React è in uso da circa cinque anni e vogliamo fare in modo che resti rilevante anche per i prossimi cinque anni. Così come Svelte, Angular, Glimmer, ed altri dimostrano, la compilazione ahead-of-time dei componenti ha molto potenziale. Specialmente se non è limitata ai templates. Recentemente, abbiamo sperimentato con il component folding utilizzando Prepack ed abbiamo ottenuto dei risultati preliminari molto promettenti. Comunque, abbiamo trovato che i componenti classe possono incoraggiare l’uso di patterns non intenzionali che possono invalidare queste ottimizzazioni facendole ricadere su percorsi più lenti. Le classi presentano problemi anche con gli strumenti ad oggi disponibili. Per esempio, non vengono minificate molto bene e rendono l’hot reloading (“caricamento a caldo”) inaffidabile. Vogliamo presentare una API che può mantenere il codice sul percorso ottimizzabile.
Per risolvere questi problemi, gli Hooks ti permettono di utilizzare più funzioni di React senza dover ricorrere alle classi. Concettualmente, i componenti React sono sempre stati più vicini alle funzioni. Gli Hooks abbracciano le funzioni, senza però sacrificare lo spirito pratico di React. Gli Hooks offrono accesso a vie di uscita imperative e non ti richiedono d’imparare complesse tecniche di programmazione funzionale o reattive.
Esempi
Panoramica sugli Hooks è un buon punto di partenza per imparare gli Hooks.
Strategie di Adozione Graduale
TLDR: Non abbiamo piani per rimuovere le classi da React.
Sappiamo che gli sviluppatori React sono focalizzati allo sviluppo di prodotti e non hanno tempo per osservare ogni nuova API appena rilasciata. Gli Hooks sono molto nuovi e potrebbe essere meglio aspettare più esempi e tutorials prima di considerarne l’apprendimento o l’adozione.
Sappiamo anche che la barra per aggiungere una nuova primitiva in React è estremamente alta. Per i lettori più curiosi, abbiamo preparato una RFC dettagliata che spiega in dettaglio le motivazioni ed offre una prospettiva aggiuntiva riguardo le decisioni di design oltre riferimenti ad opere precedenti correlate.
È importante notare che gli Hooks funzionano a fianco al codice esistente, puoi quindi adottarli in modo graduale. Non c’è fretta nella migrazione agli Hooks. Raccomandiamo di evitare “grandi riscritture”, specialmente per componenti classe complessi già esistenti. “Pensare in Hooks” richiede un po’ di cambiamenti mentali. Nella nostra esperienza, è meglio far pratica partendo da componenti nuovi e non critici, assicurandosi che tutti i membri del tuo team siano a proprio agio. Dopo che hai avuto l’opportunità di provare gli Hooks, inviaci pure un feedback, positivo o negativo.
Vogliamo far sì che gli Hooks coprano tutti i casi d’uso delle classi, tuttavia continueremo a supportare i componenti classe per il futuro prevedibile. In Facebook, abbiamo decine di migliaia di componenti scritti come classi, non abbiamo assolutamente alcun piano per riscriverli. Piuttosto, stiamo cominciando ad utilizzare gli Hooks nel nuovo codice a fianco al codice scritto usando le classi.
Domande Frequenti
Abbiamo preparato una pagina FAQ sugli Hooks che risponde alle domande più frequenti riguardo agli Hooks.
Passi Successivi
Alla fine di questa pagina, dovresti avere un’idea dei problemi che gli Hooks cercano di risolvere, anche se molti dettagli ti sembrano probabilmente non molto chiari. Non preoccuparti! Andiamo alla pagina successiva dove incominceremo ad imparare gli Hooks con esempi.