Demistificazione degli hook di React: usa Callback

Dec 03 2022
In questo articolo, esploreremo quando e come utilizzare l'hook useCallback di React e un errore commesso dalla maggior parte degli sviluppatori junior.
Per iniziare Se desideri seguire il tuo IDE locale, puoi trovare il GitHub Repo qui. L'uguaglianza referenziale è un concetto fondamentale sia in JavaScript che in Computer Science nel suo complesso.

Iniziare

Se desideri seguire il tuo IDE locale, puoi trovare il GitHub Repo qui .

  • clone
  • cd client
  • npm i
  • npm start

L'uguaglianza referenziale è un concetto fondamentale sia in JavaScript che in Computer Science nel suo complesso. Quindi iniziamo con una dimostrazione in azione.

Ho incorporato schermate in tutto l'articolo per facilità d'uso sui dispositivi mobili. Se sei sul desktop e lo hai clonato, corri referentialEquality.jsper osservare l'output o semplicemente gioca con lo snippet JSFiddle incorporato di seguito.

Quando si valuta se the integer 1è strettamente uguale a integer 1, la console stampa true. Questo perché, beh... the integer 1 è strettamente uguale a integer 1.

gli interi sono strettamente uguali

Vediamo lo stesso risultato quando si valutano due stringhe.

le stringhe sono strettamente uguali

Ovviamente, questo sarà sempre il caso di due tipi di dati primitivi dello stesso valore.

Ora, che dire delle strutture dati? Ad esempio, due oggetti letterali con le stesse coppie chiave/valore? E i letterali oggetto vuoti?

gli oggetti non sono strettamente uguali

Perché questa stampa false? Quando si confronta se questi due oggetti letterali sono strettamente uguali, JavaScript utilizza i rispettivi indirizzi di memoria .

In altre parole, questi due oggetti possono contenere gli stessi valori , ma non fanno riferimento allo stesso oggetto . Sembrano uguali ma occupano due spazi diversi nella memoria .

Lo stesso vale se stai confrontando due oggetti letterali, due array letterali o due funzioni!

gli array non sono strettamente uguali

Per dimostrarlo ulteriormente, definiremo una funzione func, che restituisce una funzione anonima che, a sua volta, restituisce qualcos'altro ( come un elemento JSX ).

creando un finto componente funzionale

Assegneremo quindi due diverse funzioni, firstRendere secondRender, pari al valore restituito da func.

assegnando le nostre definizioni di funzione

Pensa funccome il tuo componente funzionale React, mentre firstRenderè una funzione al suo interno nel primo rendering ed secondRenderè una funzione al suo interno nel secondo rendering.

Anche se firstRendere secondRenderrestituiscono lo stesso valore e sono assegnati dalla stessa definizione, non hanno uguaglianza referenziale . Di conseguenza, ogni volta che il componente esegue il rendering, ridefinisce questa funzione.

le nostre due funzioni non sono strettamente uguali

Sfortunatamente, in JavaScript, non è facile stampare questi indirizzi di memoria come in Python, ma per una spiegazione leggermente più approfondita del riferimento rispetto al valore, dai un'occhiata a questo articolo di freeCodeCamp.

Questo argomento può diventare denso e non è necessario che tu tenga una lezione su di esso stasera. Quindi, per ora, ricorda solo:

  • tipo di dati primitivo ===tipo di dati primitivo
  • struttura dati !==struttura dati.

Codice di avviamento

Dopo aver avviato la nostra app, apri il BookDetails.jsxcomponente e salva nuovamente. La prima cosa che potremmo notare nel nostro server di sviluppo React è un comune WARNINGche i giovani sviluppatori tendono a ignorare. Quando raggiungi la forza lavoro e inizi a scrivere codice per la produzione, i tuoi linter saranno ancora più rigorosi di quelli incorporati in create-react-app. WARNINGSpasserà a ERRORS, e alcuni linter non ti permetteranno di spingere prima di affrontare questi ERRORS.

Quindi, piuttosto che ignorarlo, cerchiamo di capire come trattarlo.

Le soluzioni proposte da React

NOTA: potrebbe essere necessario prima salvare nuovamente BookDetails.jsxper creare questoWARNING

Se scaviamo in React Docs , possiamo decodificare le soluzioni proposte semi-confuse a questo WARNINGcome segue:

1. Includere la definizione della funzione all'interno del file useEffect.

  • Non possiamo chiamare questa funzione altrove a meno che non la ridefiniamo.
  • Ciò attiverà useEffect ogni volta che lo stato o gli oggetti di scena cambiano, a volte causando un re-render infinito. E nel nostro caso, dal momento che stiamo chiamando la nostra funzione setter di stato dopo una chiamata API, potrebbe sovraccaricare la nostra API con infinite richieste di endpoint.
  • La funzione non verrà chiamata.
  • La prima volta che il componente esegue il rendering, definirà la nostra funzione, che attiverà il useEffect, che causerà il nuovo rendering del componente, che ridefinirà la funzione, che attiverà il useEffect, che causerà il nuovo rendering del componente, che ridefinirà la funzione...

La soluzione più semplice e preferita sarebbe "includerla", ovvero spostare la getBookDetailsdefinizione della funzione all'interno del file useEffect. Questo aderisce a un principio di programmazione orientato agli oggetti noto come Encapsulation .

Ma diciamo che sappiamo che dobbiamo chiamare la funzione altrove. Dovremmo ridefinirlo in seguito? Non è molto SECCO da parte nostra.

Modifichiamo il nostro array di dipendenze per includere il nostro riferimento alla funzione. Ora dovresti useEffectassomigliare a questo.

includendo la nostra funzione nell'array di dipendenza

E getBookDetailsrimane definito sopra il useEffect.

la definizione originale della nostra funzione

Ora abbiamo un nuovoWARNING

definire la nostra funzione al di fuori di useEffect mentre la si include nell'array di dipendenza causerà un re-render infinito

Immettere l'hook useCallback

In breve, l' useCallbackhook ti consente di memorizzare nella cache, o "memorizzare", una funzione tra i re-rendering del tuo componente. Svolge un compito simile a useMemo, le cui sfumature entreremo in un altro articolo.

Se il nocciolo di questo ti interessa, puoi leggere di più nei documenti di React .

Si prega di notare il loro avviso:

Dovresti fare affidamento solo su useCallbackcome ottimizzazione delle prestazioni. Se il tuo codice non funziona senza di esso, trova il problema sottostante e risolvilo prima. Quindi puoi aggiungere useCallbackper migliorare le prestazioni.

useCallbackSintassi

useCallbackLa sintassi di è molto simile alla useEffectsintassi di che già conosciamo. Guarda gli scheletri di ciascuno.

i due ganci hanno scheletri sintattici identici

La leggera differenza è con useEffect, diciamo alla funzione anonima di eseguire la nostra funzione mentre con useCallback, assegniamo il valore restituito a un riferimento da chiamare altrove.

Utilizzo di useCallback

Innanzitutto, importeremo useCallbackda 'react'. Piuttosto che aggiungere una nuova linea, è meglio destrutturarla insieme alle nostre altre importazioni.

gli articoli destrutturati dallo stesso pacchetto vengono importati al meglio sulla stessa linea

Ora possiamo assegnare getBookDetailsal valore restituito da una useCallbackchiamata di funzione.

assegna il ritorno di useCallback al nostro riferimento

Quindi aggiungiamo tutta la sintassi per useCallback. Ricorda il tuo array di dipendenza!

compilare lo scheletro di useCallback

Nel nostro esempio, abbiamo bisogno asyncprima dei nostri parametri.

aggiungi asincrono

Infine, aggiungiamo la logica della nostra funzione nel blocco di codice.

aggiungi la nostra logica per utilizzare il blocco di codice di Callback

Una volta salvato, otteniamo... un altro WARNING.

Il ritorno di useCallback dipende dal valore di id

Perché il nostro array di dipendenze dovrebbe tenere traccia della idvariabile?

Riflettiamo su questo.

  • Se il valore di idcambia, getBookDetailsdeve raggiungere un endpoint diverso, quindi React dovrebbe ridefinirlo. La definizione di dipendegetBookDetails letteralmente dal valore di .id
versioni finite di entrambi i ganci

E finalmente, questo è tutto! Vediamo il verde nel nostro server di sviluppo React. Un linter felice è uno sviluppatore senior felice. E un felice Senior Developer è un felice te!

Sono sempre alla ricerca di nuovi amici e colleghi. Se hai trovato utile questo articolo e desideri connetterti, puoi trovarmi in una qualsiasi delle mie case sul web.

Git Hub | Cinguettio | Linkedin | Sito web

Risorse

  • Uguaglianza referenziale
  • Tipi di dati primitivi JavaScript rispetto a strutture di dati
  • Incapsulamento
  • useCallback
  • Reagisci Documenti