In React, gli hook sono funzioni speciali che permettono agli sviluppatori di utilizzare lo stato e altre caratteristiche di React senza ricorrere a componenti di classe. Tra questi hook, l’hook useRef è uno strumento prezioso per la gestione dei valori e l’accesso agli elementi del Document Object Model (DOM).

L’hook useRef è uno strumento estremamente flessibile, ma spesso se ne fa un uso improprio.

In questo articolo analizzeremo approfonditamente l’hook useRef, chiarendone lo scopo e illustrandone le funzionalità e le best practice. Alla fine di questa guida, saprete di cosa si tratta e otterrete preziose indicazioni per sfruttare efficacemente tutto il suo potenziale.

Cos’è l’hook useRef?

useRef ha due scopi principali: memorizzare valori mutabili che non causano un nuovo rendering quando vengono aggiornati e memorizzare riferimenti a elementi del DOM. Vediamo in dettaglio.

Quando un componente viene renderizzato in React, normalmente il suo stato e le altre variabili vengono resettate. Tuttavia, ci sono casi in cui è necessario mantenere alcuni valori anche quando il componente viene renderizzato. È qui che entra in gioco l’hook useRef. Questo permette di creare un riferimento a un valore che persisterà tra un rendering e l’altro, facendo sì che il valore rimanga inalterato anche se altre parti del componente cambiano.

Inoltre, l’hook useRef è fondamentale per lavorare con gli elementi del DOM. In React, accedere e modificare direttamente gli elementi del DOM può essere difficile, soprattutto senza l’hook useRef. Con useRef si può ottenere un riferimento a un elemento specifico del DOM ed eseguire operazioni su di esso. Questo evita la necessità di librerie esterne o di complicati workaround.

Implementare useRef in React

Per utilizzare l’hook useRef in un progetto React, bisogna prima importarlo dal pacchetto React:

import { useRef } from 'react';

Una volta importato, sarà possibile dichiarare una variabile ref all’interno del componente funzionale utilizzando l’hook useRef:

const myRef = useRef();

Ora abbiamo un oggetto ref, myRef, da utilizzare per memorizzare e accedere ai valori. Per utilizzare la variabile myRef con qualsiasi elemento, basterà assegnarla alla proprietà ref dell’elemento.

<div ref={myRef}>This is an example element</div>

Nell’esempio precedente, si assegna all’elemento div una proprietà ref. Questo permette di fare riferimento e di accedere all’elemento tramite la variabile myRef in altri punti del componente.

Per accedere al valore memorizzato nel riferimento creato, si può utilizzare la proprietà .current dell’oggetto myRef.

const myRefValue = myRef.current;
console.log(myRefValue); // <div>This is a sample div</div>

Manipolare il DOM con l’Hook useRef

Spesso si ha la necessità di manipolare il DOM nello sviluppo web perché permette di modificare e aggiornare dinamicamente il contenuto, la struttura e l’aspetto di una pagina web.

Nello sviluppo JavaScript tradizionale, l’accesso e la manipolazione degli elementi del DOM richiedeva l’utilizzo di metodi come getElementById, querySelector o getElementsByClassName per selezionare elementi specifici dal documento. Una volta selezionati gli elementi, è quindi possibile aggiornarne il contenuto, modificarne gli stili o collegare gli event listener.

// HTML
<div>
  <input type="text" id="myInput" />
  <button id="focusButton">Focus Input</button>
</div>
// JavaScript
<script>
  	const inputRef = document.getElementById('myInput');
  	const focusButton = document.getElementById('focusButton');
  	const handleFocus = function() {
    	inputRef.focus();
  	};
  	focusButton.addEventListener('click', handleFocus);
</script>

Ma quando si lavora con gli elementi DOM in un componente React, il processo non è lo stesso a causa del DOM virtuale del componente e della necessità di gestire gli aggiornamenti in modo efficiente. Per accedere e manipolare gli elementi del DOM, gli sviluppatori spesso ricorrono a vari approcci, come l’utilizzo di refresh o di librerie esterne come jQuery.

Con l’introduzione dell’hook useRef di React, il lavoro con gli elementi del DOM all’interno dei componenti è stato notevolmente semplificato. L’hook useRef permette di creare un riferimento a un elemento del DOM, rendendolo facilmente accessibile e manipolabile nel contesto del componente.

import { useRef } from 'react';

const FocusComponent = () => {
  const inputRef = useRef(null);

  const handleFocus = () => {
	// accessing the input element
	let inputElement = inputRef.current;

   // modify the DOM element
   inputElement.focus();
  };
 
 return (
	<div>
  	<input type="text" ref={inputRef} />
  	<button onClick={handleFocus}>Focus Input</button>
	</div>
  );
}

In questo esempio, l’hook useRef viene utilizzato per creare un riferimento inputRef che punta all’elemento input. Quando si fa clic sul pulsante “Focus Input”, la funzione handleFocus usa inputRef.current.focus() per impostare direttamente il focus sull’elemento. Questo dimostra come l’hook useRef semplifichi il lavoro con gli elementi del DOM in React.

Un altro esempio è quello in cui si vuole manipolare un elemento div cambiandone lo sfondo al clic di un pulsante:

import { useRef } from 'react';

const ExampleComponent = () => {
  const divRef = useRef();

  const handleClick = () => {
	divRef.current.style.backgroundColor = 'red';
  };

  return (
	<div>
  	<div ref={divRef}>This is a sample div</div>
  	<button onClick={handleClick}>Change Color</button>
	</div>
  );
}

In questo esempio, creiamo un riferimento con l’hook useRef chiamato divRef. Assegniamo questo riferimento alla proprietà ref dell’elemento div.

Facendo clic sul pulsante “Change Color”, viene invocata la funzione handleClick. Nella funzione, accediamo all’elemento div con divRef.current. In questo caso, modifichiamo il colore di sfondo dell’elemento div aggiornando la sua proprietà style.backgroundColor a “red”.

divRef.current.style.backgroundColor = 'red';

Preservare i valori tra i diversi rendering

Preservare i valori tra i vari re-render è un importante caso d’uso dell’hook useRef. È utile soprattutto quando si hanno dei valori che devono persistere per tutto il ciclo di vita del componente senza che venga attivato un nuovo rendering.

Per chiarire il concetto, confrontiamo l’hook useRef con l’hook useState con degli esempi concreti:

Esempio con l’hook useState:

import { useState } from 'react';

function CounterComponent() {
  const [count, setCount] = useState(0);

  const increment = () => {
	  setCount(count + 1);
  };

  return (
	<div>
  	<p>Count: {count}</p>
  	<button onClick={increment}>Increment</button>
	</div>
  );
}

In questo esempio, utilizziamo l’hook useState per gestire la variabile di stato count. Ogni volta che viene invocata la funzione increment, lo stato count viene aggiornato utilizzando setCount. In questo modo si attiva un nuovo rendering del componente che riflette il valore aggiornato di count.

Schermata di una pagina che si riavvia con l’hook useState

Esempio con l’hook useRef:

import React, { useRef } from 'react';

function CounterComponent() {
  const countRef = useRef(0);

  const increment = () => {
  	countRef.current = countRef.current + 1;
  	console.log('Count:', countRef.current);
  };

  return (
	<div>
  	<p>Count: {countRef.current}</p>
  	<button onClick={increment}>Increment</button>
	</div>
  );
}

In questo esempio, utilizziamo l’hook useRef per creare una variabile countRef, inizializzata con un valore iniziale di 0. Ogni volta che viene invocata la funzione increment, aggiorniamo direttamente il valore di countRef.current senza attivare un nuovo rendering. Il valore aggiornato viene registrato nella console.

Schermata di una pagina che non si riavvia con l’hook useRef

Con l’hook useRef, quando il valore countRef.current cambia, non c’è il re-render del componente. Questo può essere vantaggioso in situazioni in cui i valori devono essere modificati ma non influiscono sul processo di rendering.

Si noti che quando si usa l’hook useRef in questo modo, le modifiche al valore ref non attivano automaticamente un nuovo rendering. Se si ha bisogno di riflettere il valore aggiornato nell’interfaccia utente, per ottenere il comportamento desiderato, si può gestire manualmente l’aggiornamento o combinare l’hook useRef con altri hook o variabili di stato.

Riepilogo

In questo articolo abbiamo parlato dell’hook useRef in React, ne abbiamo analizzato lo scopo, l’implementazione e le applicazioni pratiche. Abbiamo visto come utilizzare useRef per accedere e modificare gli elementi del DOM e preservare i valori.

Una delle best practice dell’hook useRef è evitare di farne un uso eccessivo. Utilizzatelo quando avete bisogno di accedere e manipolare elementi del DOM o di preservare i valori in caso di rilettura.

L’hook useRef può essere utilizzato in molti casi reali, come le animazioni e le transizioni, la memorizzazione nella cache dei valori o dei risultati intermedi e molto altro: tutti elementi che rendono unica un’applicazione React.

Distribuite gratuitamente la vostra prossima applicazione React sull’Hosting di Applicazioni di Kinsta, così potrete accedervi dal vivo e condividerla con il mondo!

Ora tocca a voi. Cosa pensate dell’hook useRef? Scrivetelo nella sezione dei commenti qui sotto.