window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = finestra if (w.LeadBooster) { console.warn('LeadBooster esiste già') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() Uno sguardo più approfondito ai ganci React più popolari - The Codest
The Codest
  • Chi siamo
  • Servizi
    • Sviluppo di software
      • Sviluppo Frontend
      • Sviluppo backend
    • Staff Augmentation
      • Sviluppatori Frontend
      • Sviluppatori backend
      • Ingegneri dei dati
      • Ingegneri del cloud
      • Ingegneri QA
      • Altro
    • Consulenza
      • Audit e consulenza
  • Industrie
    • Fintech e banche
    • E-commerce
    • Adtech
    • Tecnologia della salute
    • Produzione
    • Logistica
    • Automotive
    • IOT
  • Valore per
    • CEO
    • CTO
    • Responsabile della consegna
  • Il nostro team
  • Case Studies
  • Sapere come
    • Blog
    • Incontri
    • Webinar
    • Risorse
Carriera Contattate
  • Chi siamo
  • Servizi
    • Sviluppo di software
      • Sviluppo Frontend
      • Sviluppo backend
    • Staff Augmentation
      • Sviluppatori Frontend
      • Sviluppatori backend
      • Ingegneri dei dati
      • Ingegneri del cloud
      • Ingegneri QA
      • Altro
    • Consulenza
      • Audit e consulenza
  • Valore per
    • CEO
    • CTO
    • Responsabile della consegna
  • Il nostro team
  • Case Studies
  • Sapere come
    • Blog
    • Incontri
    • Webinar
    • Risorse
Carriera Contattate
Freccia indietro TORNA INDIETRO
2021-12-07
Sviluppo di software

Uno sguardo più approfondito ai ganci React più popolari

The Codest

Pawel Rybczynski

Software Engineer

Nel corso di molte interviste, ho notato che anche i programmatori più esperti hanno difficoltà a distinguere gli hook, per non parlare delle loro capacità più avanzate. Per questo motivo, in questo articolo cercherò di spiegare come devono essere utilizzati gli hook.

Le cose più importanti da ricordare sui ganci:

  • possono essere utilizzati solo nei componenti funzionali - i componenti di classe hanno una propria implementazione del ciclo di vita;
  • iniziano sempre con utilizzo;
  • si possono usare tutti gli agganci che si vogliono, ma bisogna ricordare che il loro uso ha un impatto sulle prestazioni complessive;
  • devono essere eseguiti nello stesso ordine su ogni rendering... ma perché? Vediamo un esempio:
importare { useState,useEffect } da "react";

esportare la funzione predefinita FunctionComponent() {
const [value, setValue] = useState(1);
const [doubleValue, setDoubleValue] = useState(1);
se (valore > 3) {
  useEffect(() => setDoubleValue(valore * 2),[value]);
}

return (
  <>
    <p>{Singolo ${valore} Doppio ${doppioValore}`}</p>
    <button onclick="{()" > setValue(valore + 1)}&gt;Controllo</button>
  </>
);
}
```

All'inizio, si riceverà un avviso da eslint:

<code>srcFunctionComponent.js
   Riga 11:5: React Il gancio "useEffect" è chiamato in modo condizionato. <strong>React Ganci</strong> deve essere chiamato esattamente nello stesso ordine in ogni componente render .eslintreact-hooks/rules-of-hooks

Come si può vedere, si tratta solo di un avviso di eslint, quindi è possibile disabilitarlo aggiungendo un comando dal basso all'inizio del file FunzioneComponente

/* eslint-disable react-hooks/rules-of-hooks */ 

e funzionerà, ma solo finché non verrà soddisfatta la condizione che fa funzionare il nostro Hook. La cosa successiva che vedremo è questo errore.

Errore non corretto: Renderizzati più ganci rispetto al rendering precedente.
     React 5
     FunctionComponent FunctionComponent.js:11
     React 12
     unstable_runWithPriority scheduler.development.js:468
     React 17
     js index.js:7
     js main.chunk.js:905
     Webpack 7
 react-dom.development.js:15162

Perché questo accade? L'React si basa sull'ordine in cui vengono chiamati gli hook, in quanto l'React non saprebbe cosa restituire per l'useEffect perché non c'è un hook nella riga da controllare.

Ricordate che eslint è uno strumento potente, che ci aiuta a individuare molti potenziali bug ed errori. Disattivare i suoi avvisi è una cosa pericolosa, controllate sempre se ignorare l'avviso può causare un crash dell'applicazione.

Stato d'uso

Probabilmente sapete come si presenta 😉

const [value, setValue] = useState(0);

Quindi, ci sono 4 elementi: stato (valore reattivo), funzione di aggiornamento (setter), aggancio effettivo (funzione) e valore iniziale opzionale. Perché restituisce un array? Perché possiamo ristrutturarlo come vogliamo.

Ora voglio concentrarmi sull'ultimo elemento: il valore iniziale. Esistono due modi per passare lo stato iniziale:

  1. Con un valore predefinito o altro, che verrà richiamato a ogni rendering.
const [value, setValue] = useState(0);
  1. Da una versione di funzione. È molto utile se si vuole eseguire lo stato iniziale solo una volta, al primo rendering. Forse è necessario eseguire molti calcoli complessi per ricevere lo stato iniziale? In questo modo si riduce il costo delle risorse, evviva!
const [value, setValue] = useState(() => {
   console.log("INIT");
   return 0;
 });

Come verificare che il primo modo sia davvero chiamato ad ogni rendering? Creare una funzione e passarla come stato iniziale:

const checkInit = () => {
console.log("INIT");
return 0;
};

const [value, setValue] = useState(checkInit());
```

E ora passate al secondo modo:

const checkInit = () => {
console.log("INIT");
return 0;
};

const [value, setValue] = useState(() => checkInit());
```

Bello, vero?

rumore.png

Un'altra cosa che può creare bug nel flusso dell'app: probabilmente sapete come aggiornare uno stato, giusto?

setValue(1);

Giusto... ma se volessi aggiornare lo stato in base a uno stato precedente?

setValue(valore + 1);

Sì... Ma no... E se si cerca di chiamare la funzione setter due volte, una dopo l'altra? Il modo consigliato per aggiornare uno stato in base allo stato precedente è utilizzare una funzione. Garantisce che si stia facendo riferimento allo stato precedente

setValue((prevState) => prevState + 1);
// con gli oggetti:
setUser((prevState) => ({ ...prevState, lastName: "Brzeczyszczykiewicz" }));

usaEffetto

Questo hook accetta due argomenti (il secondo è opzionale) e lo usiamo per gestire gli effetti collaterali. A seconda di ciò che passiamo come secondo argomento, l'hook sarà chiamato in modo diverso:

  1. senza secondo argomento - ogni rendering
useEffect(() => {
   doSomething();
 });
  1. array vuoto - solo al primo rendering
useEffect(() => {
   doSomething();
 }, []);
  1. con le dipendenze - ogni volta che il valore nell'array delle dipendenze cambia
useEffect(() => {
   doSomething(valore);
 }, [valore]);

Pulizia

Con useEffect, possiamo usare qualcosa che viene chiamato cleanup. A cosa serve? È molto utile, ma credo sia meglio per pulire gli ascoltatori di eventi. Supponiamo di voler creare un ascoltatore di eventi che dipende da alcuni stati. Non si vuole aggiungere un nuovo ascoltatore di eventi a ogni cambio di stato, perché dopo qualche rendering ci saranno così tanti ascoltatori da influire sulle prestazioni dell'applicazione. Un ottimo modo per evitare queste cose è usare la funzione di pulizia. Come fare? Basta aggiungere una funzione di ritorno a useEffect.

useEffect(() => {
console.log("effetto collaterale 1", count);
return () => {
console.log("DISTRUTTO 1");
};
});

useEffect(() => {
console.log("effetto collaterale 2", count);
return () => {
console.log("DISTRUTTO 2");
};
}, []);

useEffect(() => {
console.log("effetto collaterale 3", count);
return () => {
console.log("DISTRUTTO 3");
};
}, [count]);
```

Poiché si trova all'interno dell'hook useEffect, il ritorno viene chiamato a seconda dell'array di dipendenze: a ogni rendering, solo al primo rendering o quando il valore nell'array di dipendenze cambia. Ma quando il componente viene smontato, la pulizia sarà chiamata sul secondo parametro, indipendentemente da ciò. Il ritorno codice viene richiamato prima del codice effettivo di Hook. È molto logico: prima si pulisce quello vecchio, poi se ne crea uno nuovo. Giusto?

useEffect(() => {
   // addEventListener
   console.log("Aggiungi");
   return () => {
     // removeEventListener
     console.log("Rimuovi");
   };
 }, [value]);

Quindi, per prima cosa, riceverete un rimuovere messaggio, allora Aggiungi.

C'è una cosa da tenere presente quando si usa useEffect e il codice asincrono al suo interno. Date un'occhiata al codice qui sotto:

useEffect(() => {
   fetch("https://picsum.photos/5000/5000").then(() => {
     setValue((prevState) => prevState + 1);
   });
 }, []);

All'inizio sembra tutto a posto. Si recuperano alcuni dati e, quando questi arrivano, si aggiorna lo stato. Ed ecco la trappola:

A volte si riceve un avviso di questo tipo:
Impossibile eseguire un aggiornamento di stato React su un componente non montato. Si tratta di un'operazione non necessaria, ma indica una perdita di memoria nell'applicazione. Per risolvere, annullare tutte le sottoscrizioni e le attività asincrone in una funzione di pulizia useEffect.

Il motivo è che il componente può essere smontato nel frattempo, ma l'applicazione cercherà comunque di aggiornare lo stato del componente dopo che la promessa è stata mantenuta. Come comportarsi? È necessario verificare se il componente esiste.

useEffect(() => {
let mounted = true;
fetch("https://picsum.photos/5000/5000").then(() => {
if (mounted) {
setValue((prevState) => prevState + 1);
}
});

return () => {
montato = false;
};
}, []);
```

Nota: esiste un hook molto simile => useLayoutEffect() - il callback viene eseguito dopo il rendering del componente, ma prima che la dom venga aggiornata visivamente. È utile quando si lavora con getBoundingClientRect(), ma si dovrebbe usare useEffect per impostazione predefinita. Perché? Perché può bloccare gli aggiornamenti visivi, quando si ha un codice complesso all'interno dell'effetto Hook.

usaContext

A cosa serve? Condividere dati senza passare oggetti di scena. Consiste nei seguenti elementi:

  1. Contesto creato - dati
  2. Fornitore di contesto - fornire un contesto a tutti i bambini
  3. Valore passato - dati che si desidera condividere
  4. Gancio - per leggere i dati condivisi
const utente = {
nome: "Adam",
cognome: "Kowalski",
};

export const UserContext = createContext(user);

;
```

In child, è necessario importare il contesto e chiamare l'hook useContext, passando il contesto come argomento.

importare { UserContext } da "./App";

const { name } = useContext(UserContext);

restituire <h1>Ciao {nome}<>
```

Voilà. Sembra bello. Soprattutto per passare dati globali come temi, ecc. Non è raccomandato per l'uso in attività con modifiche molto dinamiche.

Naturalmente, possiamo creare un fornitore di contesto personalizzato e un hook personalizzato per ridurre il boilerplate... ma tratterò gli hook personalizzati nel prossimo articolo.

usaRiduttore

Ci consente di gestire lo stato e di renderizzare nuovamente quando lo stato cambia, come useState. È simile al redux reducer. È meglio di useState quando la logica dello stato è più complicata.

const [state, dispatch] = useReducer(reducer, initialArg); 
  • Restituisce lo stato attuale con un metodo di invio.
  • A differenza di redux, il valore iniziale viene specificato quando viene chiamato l'hook.

Esiste anche un terzo argomento che può essere passato a useReducer: la funzione init.

const [state, dispatch] = useReducer(reducer, initialArg, init);

A cosa serve? Può essere utilizzato quando si vuole riportare lo stato al suo valore iniziale. Di seguito è riportato un simpatico esempio:

// Genitore
// Bambino
function init(initialNumber) {
return { numero: initialNumber };
}

function reducer(state, action) {
switch (action.type) {
caso "change":
return { numero: Math.random() };
caso "reset":
return init(action.payload);
default:
throw new Error();
}
}

Esportare la funzione predefinita ChildComponent({ getFactorial }) {
const [state, dispatch] = useReducer(reducer, initialNumber, init);

return (
<>
   <h2>Numero: {state.number}</h2>
      <button
        onclick="{()" > dispatch({tipo: "reset", payload: initialNumber })}
      &gt;
        Azzeramento
      </button>
      <button onclick="{()" > dispatch({tipo: "change" })}&gt;Disegna</button>
    </>
  );
}

Numero: {state.number}

ReducerInit.png

useCallback

Quando usarlo? Quando si vuole ottenere l'uguaglianza referenziale (riducendo così il numero di funzioni create). Questo hook restituisce la funzione, a differenza di useMemo che restituisce il valore.

Esempio: Creare una funzione nel componente padre e poi passarla tramite gli oggetti di scena

// Genitore
 const getSquaredValue = () => count * count;
 ...
 return (
   
 )

Quindi verificare nel componente figlio quante volte verrà richiamato l'effetto Hook dopo aver aggiunto la funzione all'array delle dipendenze:

// Bambino
 useEffect(() => {
   console.log("getSquaredValue", getSquaredValue());
 }, [getSquaredValue]);

Verrà registrato nella console a ogni rendering! Anche se i valori all'interno del campo getSquaredValue() non è stata modificata. Ma possiamo evitarlo avvolgendo la funzione in useCallback

const getSquaredValue = useCallback(() => count * count, [count])

Possiamo anche passare alcuni parametri a questa funzione:

const getSquaredValue = useCallback(
   (moltiplicatore) => conteggio * conteggio * moltiplicatore,
   [count]
 );

usaMemo

const memoizedValue = useMemo(() => {
   return doSomething(valore);
 }, [valore]);
  • Non è neutrale se si considerano i costi delle risorse: useMemo deve essere richiamato a ogni rendering, salva il valore in memoria e lo confronta (overhead di memoria),
  • utilizza la Memoization, una tecnica di ottimizzazione, una forma specifica di caching.

Dovreste usarlo solo in due scenari:

  1. Se si vuole evitare di richiamare un codice complesso a ogni rendering;
  2. Se si vuole ottenere l'uguaglianza referenziale.

Vediamo un po' più da vicino il secondo caso. Vogliamo usare useEffect con un oggetto come dipendenza. Poiché gli oggetti sono confrontati in base al loro riferimento, useEffect sarà richiamato a ogni rendering. Per evitare questo, possiamo combinare useEffect con useMemo per memorizzare tali oggetti e poi passare gli oggetti memorizzati all'array delle dipendenze. Breve esempio:

Per prima cosa provate a farlo senza useMemo:

const hobbit = { nome: "Bilbo" };

useEffect(() => {
console.log("Ciao ", nome.hobbit);
}, [hobbit]);
```

Inoltre, riceverete un avviso:

L'oggetto 'hobbit' fa cambiare le dipendenze del gancio useEffect (riga 49) a ogni rendering. Spostarlo all'interno del callback useEffect. In alternativa, avvolgere l'inizializzazione di 'hobbit' nel proprio hook useMemo ().eslintreact-hooks/exhaustive-deps

Poi provate con useMemo:

const hobbit = useMemo(() => {
return { nome: "Bilbo" };
}, []);

useEffect(() => {
console.log("Ciao ", nome.hobbit);
}, [hobbit]);
```

usaRef

La cosa più importante è che useRef non attiva il re-rendering (come useState) perché non è collegato al ciclo di rendering: mantiene lo stesso riferimento tra i rendering.

const ref = useRef(0);

Per richiamare il valore salvato, è necessario utilizzare una proprietà current (ref è un oggetto) - corrente

Il secondo caso in cui possiamo usare questo hook è per fare riferimento a elementi all'interno dell'HTML. Ogni elemento ha un attributo ref. Quindi, possiamo gestire il focus, gli eventi e così via.

Il terzo caso è quello in cui possiamo usare i refs per gestire componenti non controllati. Si può leggere di più su di essi in documenti di react,
ma, in breve, si presenta così:

esportare la funzione predefinita UncontrolledForm() {
  const input = useRef();

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(input.current.value);
  };

  return (
    
      
      
    
  );
}

Come si può vedere, non c'è un gestore di eventi, ma solo la memorizzazione del valore digitato. È ottimo per gestire i moduli di base, quando si vuole solo leggere i valori salvati quando se ne ha bisogno (come al momento dell'invio).

Bonus: è ottimo quando si ha bisogno di ricordare i valori di uno stato precedente. Si può usare il gancio useEffect, basta passare lo stato al ref.

const [value, setValue] = useState("");

let prevValue = useRef("");

useEffect(() => {
  prevValue.current = valore;
}, [valore]);

 setValue(e.target.value)}>;

Come si può vedere, i ganci non sono così ovvi. Possiamo combinarli per risolvere molti problemi. Sicuramente trarrete grandi benefici dallo studio di questo argomento.

E ci sono anche ganci personalizzati...

In conclusione, Ganci React hanno rivoluzionato il modo in cui Sviluppatori React approccio all'edificio applicazioni web . Fornendo un modo più intuitivo ed efficiente per gestire lo stato e il ciclo di vita dei componenti funzionali, i ganci sono diventati parte integrante del sistema di gestione delle risorse. Sviluppo React .

Sia che siate sviluppatori esperti o che abbiate appena iniziato a usare l'React, la comprensione dei ganci più popolari e dei loro casi d'uso è fondamentale. Con ganci come useState, useEffect, useContext e altri ancora, Componenti React possono essere costruiti con codice più pulito e riutilizzabile. Inoltre, la possibilità di creare ganci personalizzati consente agli sviluppatori di incapsulare e condividere la logica tra più componenti, favorendo la riusabilità e la modularità del codice. Man mano che React continuerà a evolversi e a introdurre nuove funzionalità, gli agganci svolgeranno senza dubbio un ruolo centrale nello sfruttare appieno il potenziale del framework.

Quindi, sia che si stia lavorando a una piccola applicazione funzionale o a un'applicazione web su larga scala, abbracciare Ganci React migliorerà il vostro flusso di lavoro di sviluppo e aprirà una pletora di possibilità per la creazione di prodotti robusti e ricchi di funzionalità. Applicazioni React .

Fine della Parte 1

Per saperne di più:

L'JavaScript è completamente morto. Un tizio su Internet

Distribuire API GraphQL/MongoDB utilizzando le funzioni Netlify

Come uccidere un progetto con cattive pratiche di codifica

Articoli correlati

Sviluppo di software

Costruire applicazioni web a prova di futuro: le intuizioni del team di esperti di The Codest

Scoprite come The Codest eccelle nella creazione di applicazioni web scalabili e interattive con tecnologie all'avanguardia, offrendo esperienze utente senza soluzione di continuità su tutte le piattaforme. Scoprite come la nostra esperienza favorisce la trasformazione digitale e il business...

IL CANCRO
Sviluppo di software

Le 10 principali aziende di sviluppo software con sede in Lettonia

Scoprite le migliori aziende di sviluppo software della Lettonia e le loro soluzioni innovative nel nostro ultimo articolo. Scoprite come questi leader tecnologici possono aiutarvi a migliorare la vostra attività.

thecodest
Soluzioni per aziende e scaleup

Essenziali di sviluppo software Java: Guida all'outsourcing di successo

Esplorate questa guida essenziale sullo sviluppo di software Java con successo outsourcing per migliorare l'efficienza, accedere alle competenze e guidare il successo del progetto con The Codest.

thecodest
Sviluppo di software

La guida definitiva all'outsourcing in Polonia

L'aumento di outsourcing in Polonia è guidato dai progressi economici, educativi e tecnologici, che favoriscono la crescita dell'IT e un clima favorevole alle imprese.

IlCodesto
Soluzioni per aziende e scaleup

Guida completa agli strumenti e alle tecniche di audit IT

Gli audit IT garantiscono sistemi sicuri, efficienti e conformi. Per saperne di più sulla loro importanza, leggete l'articolo completo.

The Codest
Jakub Jakubowicz CTO e cofondatore

Iscrivetevi alla nostra knowledge base e rimanete aggiornati sulle competenze del settore IT.

    Chi siamo

    The Codest - Società internazionale di sviluppo software con centri tecnologici in Polonia.

    Regno Unito - Sede centrale

    • Ufficio 303B, 182-184 High Street North E6 2JA
      Londra, Inghilterra

    Polonia - Poli tecnologici locali

    • Parco uffici Fabryczna, Aleja
      Pokoju 18, 31-564 Cracovia
    • Ambasciata del cervello, Konstruktorska
      11, 02-673 Varsavia, Polonia

      The Codest

    • Casa
    • Chi siamo
    • Servizi
    • Case Studies
    • Sapere come
    • Carriera
    • Dizionario

      Servizi

    • Consulenza
    • Sviluppo di software
    • Sviluppo backend
    • Sviluppo Frontend
    • Staff Augmentation
    • Sviluppatori backend
    • Ingegneri del cloud
    • Ingegneri dei dati
    • Altro
    • Ingegneri QA

      Risorse

    • Fatti e miti sulla collaborazione con un partner esterno per lo sviluppo di software
    • Dagli Stati Uniti all'Europa: Perché le startup americane decidono di trasferirsi in Europa
    • Confronto tra gli hub di sviluppo Tech Offshore: Tech Offshore Europa (Polonia), ASEAN (Filippine), Eurasia (Turchia)
    • Quali sono le principali sfide di CTO e CIO?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Condizioni di utilizzo del sito web

    Copyright © 2025 di The Codest. Tutti i diritti riservati.

    it_ITItalian
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek it_ITItalian