Introduzione all'API React Hooks
Pubblicato: 2022-03-10Quando React 16.8 è stato rilasciato ufficialmente all'inizio di febbraio 2019, è stato fornito con un'API aggiuntiva che ti consente di utilizzare lo stato e altre funzionalità in React senza scrivere una classe. Questa API aggiuntiva si chiama Hooks e stanno diventando popolari nell'ecosistema React, dai progetti open source all'utilizzo nelle applicazioni di produzione.
I React Hook sono completamente opt-in, il che significa che la riscrittura del codice esistente non è necessaria, non contengono modifiche di rilievo e sono disponibili per l'uso con il rilascio di React 16.8. Alcuni sviluppatori curiosi hanno utilizzato l'API Hooks anche prima che fosse rilasciata ufficialmente, ma all'epoca non era stabile ed era solo una funzionalità sperimentale. Ora è stabile e consigliato agli sviluppatori React da usare.
Nota : non parleremo di React o JavaScript in generale. Una buona conoscenza di ReactJS e JavaScript ti sarà utile mentre lavori in questo tutorial.
Cosa sono i React Hook?
I React Hook sono funzioni integrate che consentono agli sviluppatori React di utilizzare metodi di stato e ciclo di vita all'interno di componenti funzionali, inoltre lavorano insieme al codice esistente, quindi possono essere facilmente adottati in una base di codice. Il modo in cui gli Hook sono stati presentati al pubblico era che consentono agli sviluppatori di utilizzare lo stato nei componenti funzionali, ma sotto il cofano, gli Hook sono molto più potenti di così. Consentono agli sviluppatori React di godere dei seguenti vantaggi:
- Riutilizzo del codice migliorato;
- Migliore composizione del codice;
- Default migliori;
- Condivisione della logica non visiva con l'uso di hook personalizzati;
- Flessibilità nel movimento su e giù per l'albero dei
components
.
Con React Hooks, gli sviluppatori ottengono il potere di utilizzare componenti funzionali per quasi tutto ciò che devono fare, dal solo rendering dell'interfaccia utente alla gestione dello stato e anche della logica, il che è piuttosto accurato.
Motivazione dietro il rilascio di ganci React
Secondo la documentazione ufficiale di ReactJS, le seguenti sono le motivazioni alla base del rilascio di React Hooks:
- Riutilizzare la logica stateful tra i componenti è difficile.
Con Hooks puoi riutilizzare la logica tra i tuoi componenti senza cambiarne l'architettura o la struttura. - I componenti complessi possono essere difficili da capire.
Quando i componenti diventano più grandi ed eseguono molte operazioni, diventa difficile da capire a lungo termine. Gli hook risolvono questo problema consentendo di separare un particolare singolo componente in varie funzioni più piccole in base a quali parti di questo componente separato sono correlate (come impostare un abbonamento o recuperare dati), piuttosto che dover forzare una divisione in base ai metodi del ciclo di vita. - Le lezioni sono piuttosto confuse.
Le lezioni sono un ostacolo all'apprendimento Reagire correttamente; dovresti capire come funziona in JavaScriptthis
differisce dalle altre lingue. React Hooks risolve questo problema consentendo agli sviluppatori di utilizzare il meglio delle funzionalità di React senza dover utilizzare le classi.
Le regole dei ganci
Ci sono due regole principali che devono essere rigorosamente rispettate come affermato dal core team di React in cui sono delineate nella documentazione della proposta di hooks.
- Assicurati di non utilizzare Hook all'interno di loop, condizioni o funzioni nidificate;
- Utilizzare solo ganci dall'interno di React Functions.
Ganci di reazione di base
Ci sono 10 hook integrati che sono stati spediti con React 16.8, ma gli hook di base (di uso comune) includono:
-
useState()
-
useEffect()
-
useContext()
-
useReducer()
Questi sono i 4 hook di base comunemente usati dagli sviluppatori React che hanno adottato React Hooks nelle loro codebase.
useState()
L' useState()
consente agli sviluppatori React di aggiornare, gestire e manipolare lo stato all'interno dei componenti funzionali senza doverlo convertire in un componente di classe. Usiamo il frammento di codice qui sotto è un semplice componente Age counter e lo useremo per spiegare la potenza e la sintassi useState()
.
function App() { const [age, setAge] = useState(19); const handleClick = () => setAge(age + 1) return <div> I am {age} Years Old <div> <button onClick={handleClick}>Increase my age! </button> </div> </div> }
Se hai notato, il nostro componente sembra piuttosto semplice, conciso e ora è un componente funzionale e inoltre non ha il livello di complessità che avrebbe un componente di classe.
L' useState()
riceve uno stato iniziale come argomento e quindi restituisce, utilizzando la destrutturazione dell'array in JavaScript, le due variabili nell'array possono essere denominate what. La prima variabile è lo stato attuale, mentre la seconda variabile è una funzione che ha lo scopo di aggiornare lo stato fornendo un nuovo stato.

Ecco come dovrebbe apparire il nostro componente quando viene renderizzato nella nostra applicazione React. Facendo clic sul pulsante "Aumenta la mia età", lo stato dell'età cambierà e il componente funzionerà proprio come un componente di classe con stato.
useEffect()
L' useEffect()
accetta una funzione che conterrebbe codice efficace. Nei componenti funzionali, effetti come mutazioni, abbonamenti, timer, registrazione e altri effetti non possono essere inseriti all'interno di un componente funzionale perché ciò comporterebbe molte incoerenze durante il rendering dell'interfaccia utente e anche bug confusi.
Utilizzando l' useEffect()
, la funzione efficace passata in esso verrà eseguita subito dopo che il rendering è stato visualizzato sullo schermo. Gli effetti sono fondamentalmente sbirciati nel modo imperativo di costruire interfacce utente che è abbastanza diverso dal modo funzionale di React.
Per impostazione predefinita, gli effetti vengono eseguiti principalmente dopo che il rendering è stato completato, ma hai la possibilità di attivarli anche quando cambiano determinati valori.
L' useEffect()
entra in gioco principalmente per gli effetti collaterali che vengono solitamente utilizzati per le interazioni con l'API Browser/DOM o per il recupero o le iscrizioni di dati simili a API esterne. Inoltre, se hai già familiarità con il funzionamento dei metodi del ciclo di vita di React, puoi anche pensare a useEffect()
hook come montaggio , aggiornamento e smontaggio di componenti, il tutto combinato in un'unica funzione. Ci consente di replicare i metodi del ciclo di vita nei componenti funzionali.
Useremo i frammenti di codice di seguito per spiegare il modo più semplice possibile utilizzando l' useEffect()
.
Passaggio 1: definisci lo stato della tua applicazione
import React, {useState} from 'react'; function App() { //Define State const [name, setName] = useState({firstName: 'name', surname: 'surname'}); const [title, setTitle] = useState('BIO'); return( <div> <h1>Title: {title}</h1> <h3>Name: {name.firstName}</h3> <h3>Surname: {name.surname}</h3> </div> ); }; export default App
Proprio come abbiamo discusso nella sezione precedente su come utilizzare l' useState()
per gestire lo stato all'interno dei componenti funzionali, lo abbiamo usato nel nostro frammento di codice per impostare lo stato per la nostra app che rende il mio nome completo.
Passaggio 2: chiama il gancio useEffect
import React, {useState, useEffect} from 'react'; function App() { //Define State const [name, setName] = useState({firstName: 'name', surname: 'surname'}); const [title, setTitle] = useState('BIO'); //Call the use effect hook useEffect(() => { setName({FirstName: 'Shedrack', surname: 'Akintayo'}) }, [])//pass in an empty array as a second argument return( <div> <h1>Title: {title}</h1> <h3>Name: {name.firstName}</h3> <h3>Surname: {name.surname}</h3> </div> ); }; export default App
Ora abbiamo importato l'hook useEffect
e abbiamo anche usato la funzione useEffect()
per impostare lo stato della nostra proprietà name e surname che è abbastanza chiara e concisa.
Potresti aver notato l'hook useEffect
nel secondo argomento che è un array vuoto; questo perché contiene una chiamata a setFullName
che non ha un elenco di dipendenze. Il passaggio del secondo argomento impedirà una catena infinita di aggiornamenti ( componentDidUpdate()
) e consentirà anche al nostro useEffect()
di agire come un metodo del ciclo di vita componentDidMount
ed eseguire il rendering una volta senza eseguire nuovamente il rendering su ogni modifica nell'albero.
La nostra app React ora dovrebbe apparire così:

useEffect
Hook (Anteprima grande) Possiamo anche usare change the title
proprietà della nostra applicazione all'interno della funzione useEffect()
chiamando la funzione setTitle()
, in questo modo:

import React, {useState, useEffect} from 'react'; function App() { //Define State const [name, setName] = useState({firstName: 'name', surname: 'surname'}); const [title, setTitle] = useState('BIO'); //Call the use effect hook useEffect(() => { setName({firstName: 'Shedrack', surname: 'Akintayo'}) setTitle({'My Full Name'}) //Set Title }, [])// pass in an empty array as a second argument return( <div> <h1>Title: {title}</h1> <h3>Name: {name.firstName}</h3> <h3>Surname: {name.surname}</h3> </div> ); }; export default App
Ora, dopo che la nostra applicazione è stata renderizzata, ora mostra il nuovo titolo.

useContext()
L' useContext()
accetta un oggetto di contesto, ovvero il valore restituito da React.createContext
, e quindi restituisce il valore di contesto corrente per quel contesto.
Questo hook offre ai componenti funzionali un facile accesso al contesto dell'app React. Prima dell'introduzione dell'hook useContext
, avresti bisogno di impostare un contextType
o un <Consumer>
per accedere al tuo stato globale passato da qualche provider in un componente di classe.
Fondamentalmente, l'hook useContext
funziona con l'API React Context, che è un modo per condividere i dati in profondità nell'app senza la necessità di passare manualmente gli oggetti di scena dell'app attraverso vari livelli. Ora, useContext()
rende un po' più semplice l'uso di Context.
I frammenti di codice seguenti mostreranno come funziona l'API Context e come l'hook useContext
la migliora.
Il modo normale di utilizzare l'API Context
import React from "react"; import ReactDOM from "react-dom"; const NumberContext = React.createContext(); function App() { return ( <NumberContext.Provider value={45}> <div> <Display /> </div> </NumberContext.Provider> ); } function Display() { return ( <NumberContext.Consumer> {value => <div>The answer to the question is {value}.</div>} </NumberContext.Consumer> ); } ReactDOM.render(<App />, document.querySelector("#root"));
Analizziamo ora il frammento di codice e spieghiamo ogni concetto.
Di seguito, stiamo creando un contesto chiamato NumberContext
. Ha lo scopo di restituire un oggetto con due valori: { Provider, Consumer }
.
const NumberContext = React.createContext();
Quindi utilizziamo il valore Provider
che è stato restituito dal NumberContext
che abbiamo creato per rendere disponibile un valore particolare a tutti i bambini.
function App() { return ( <NumberContext.Provider value={45}> <div> <Display /> </div> </NumberContext.Provider> ); }
Con ciò, possiamo utilizzare il valore Consumer
che è stato restituito dal NumberContext
che abbiamo creato per ottenere il valore che abbiamo reso disponibile a tutti i bambini. Se hai notato, questo componente non ha ricevuto alcun oggetto di scena.
function Display() { return ( <NumberContext.Consumer> {value => <div>The answer to the question is {value}.</div>} </NumberContext.Consumer> ); } ReactDOM.render(<App />, document.querySelector("#root"));
Nota come siamo stati in grado di ottenere il valore dal componente App
nel componente Display
avvolgendo il nostro contenuto in un NumberContext.Consumer
e usando il metodo render props per recuperare il valore ed eseguirne il rendering.
Tutto funziona bene e il metodo di rendering che abbiamo utilizzato è un ottimo modello per la gestione dei dati dinamici, ma a lungo termine introduce un po' di annidamento e confusione non necessari se non ci sei abituato.
Utilizzo del metodo useContext
Per spiegare il metodo useContext
riscriveremo il componente Display
usando l'hook useContext.
// import useContext (or we could write React.useContext) import React, { useContext } from 'react'; // old code goes here function Display() { const value = useContext(NumberContext); return <div>The answer is {value}.</div>; }
Questo è tutto ciò che dobbiamo fare per mostrare il nostro valore. Abbastanza pulito, vero? Chiamate l'hook useContext()
e passate l'oggetto contesto che abbiamo creato e ne prendiamo il valore.
Nota: non dimenticare che l'argomento passato all'hook useContext deve essere l'oggetto di contesto stesso e qualsiasi componente che chiama useContext eseguirà sempre il rendering di nuovo quando il valore di contesto cambia.
useReducer()
L'hook useReducer
viene utilizzato per la gestione di stati complessi e transizioni di stato. reducer
una funzione di riduzione e anche un input di stato iniziale; quindi, restituisce lo stato corrente e anche una funzione di dispatch
come output mediante la destrutturazione dell'array.
Il codice seguente è la sintassi corretta per l'utilizzo dell'hook useReducer
.
const [state, dispatch] = useReducer(reducer, initialArg, init);
È una sorta di alternativa useState
; di solito è preferibile useState
quando si ha una logica di stato complessa che ha a che fare con più sottovalori o quando lo stato successivo dipende da quello precedente.
Altri ganci React disponibili
useCallback | Questo hook restituisce una funzione di callback memorizzata e che cambia solo se cambia una dipendenza nell'albero delle dipendenze. |
useMemo | Questo hook restituisce un valore memorizzato, puoi passare una funzione "crea" e anche un array di dipendenze. Il valore restituito utilizzerà nuovamente il valore memorizzato solo se una delle dipendenze nell'albero delle dipendenze cambia. |
useRef | Questo hook restituisce un oggetto ref mutabile la cui proprietà .current viene inizializzata sull'argomento passato ( initialValue ). L'oggetto restituito sarà disponibile per l'intera durata del componente. |
useImperativeHandle | Questo hook viene utilizzato per personalizzare il valore dell'istanza reso disponibile per i componenti principali quando si utilizzano i riferimenti in React. |
useLayoutEffect | Questo hook simile useEffect , tuttavia, si attiva in modo sincrono dopo tutte le mutazioni DOM. Inoltre, esegue il rendering allo stesso modo di componentDidUpdate e componentDidMount . |
useDebugValue | Questo hook può essere utilizzato per visualizzare un'etichetta per hook personalizzati in React Dev Tools. È molto utile per il debug con React Dev Tools. |
Ganci di reazione personalizzati
Un "Hook personalizzato" è una funzione JavaScript i cui nomi sono preceduti dalla parola use
e può essere utilizzata per chiamare altri Hook. Consente inoltre di estrarre la logica dei componenti in funzioni riutilizzabili; sono normali funzioni JavaScript che possono utilizzare altri Hook al suo interno e contengono anche una logica stateful comune che può essere utilizzata all'interno di più componenti.
I frammenti di codice seguenti mostrano un esempio di React Hook personalizzato per l'implementazione di scorrimento infinito (di Paulo Levy):
import { useState } from "react"; export const useInfiniteScroll = (start = 30, pace = 10) => { const [limit, setLimit] = useState(start); window.onscroll = () => { if ( window.innerHeight + document.documentElement.scrollTop === document.documentElement.offsetHeight ) { setLimit(limit + pace); } }; return limit; };
Questo Hook personalizzato accetta due argomenti che sono start
e pace
. L'argomento iniziale è il numero iniziale di elementi di cui eseguire il rendering mentre l'argomento ritmo è il numero successivo di elementi di cui eseguire il rendering. Per impostazione predefinita, gli argomenti start
e pace
sono impostati rispettivamente su 30
e 10
, il che significa che puoi effettivamente chiamare Hook senza alcun argomento e verranno invece utilizzati quei valori predefiniti.
Quindi, per utilizzare questo Hook all'interno di un'app React, lo useremmo con un'API online che restituisce dati "falsi":
import React, { useState, useEffect } from "react"; import { useInfiniteScroll } from "./useInfiniteScroll"; const App = () => { let infiniteScroll = useInfiniteScroll(); const [tableContent, setTableContent] = useState([]); useEffect(() => { fetch("https://jsonplaceholder.typicode.com/todos/") .then(response => response.json()) .then(json => setTableContent(json)); }, []); return ( <div style={{ textAlign: "center" }}> <table> <thead> <tr> <th>User ID</th> <th>Title</th> </tr> </thead> <tbody> {tableContent.slice(0, infiniteScroll).map(content => { return ( <tr key={content.id}> <td style={{ paddingTop: "10px" }}>{content.userId}</td> <td style={{ paddingTop: "10px" }}>{content.title}</td> </tr> ); })} </tbody> </table> </div> ); }; export default App;
Il codice sopra visualizzerà un elenco di dati falsi ( userID
e title
) che utilizzano il gancio di scorrimento infinito per visualizzare il numero iniziale di dati sullo schermo.
Conclusione
Spero che ti sia piaciuto lavorare con questo tutorial. Puoi sempre leggere di più su React Hooks dai riferimenti seguenti.
Se avete domande, potete lasciarle nella sezione commenti e sarò felice di rispondere a tutte!
Il repository di supporto per questo articolo è disponibile su Github.
Risorse e ulteriori letture
- "Riferimento API Hooks", React.js Docs
- "Cosa sono i React Hook?", Robin Wieruch
- "Come funziona l'hook
useContext
", Dave Ceddia - "React Hooks: come utilizzare
useEffect()
", Hossein Ahmadi, Medium - "Scrivere i tuoi hook di reazione personalizzati", Aayush Jaiswal, medio
- "Ricette di reazione facili da capire", Gabe Ragland, useHooks()