# useCallback: the use that pays and the noise

useCallback keeps a function's identity stable between renders. It pays when that function is a dependency in an effect or a prop of a memoised child.

> Page: https://ui.eneawork.it/blog/usecallback-uso-reale
> Markdown: https://ui.eneawork.it/blog/usecallback-uso-reale.md

*2026-11-01*

useCallback restituisce la stessa funzione fra due render finché le dipendenze non cambiano. Conviene quando quell’identità è una dipendenza in un effect o una prop di un componente memo; altrove è rumore.

Il catalogo EneUI conta 111.985 componenti, 1.556 blocchi e 12.808 icone da 1.472 librerie, misurati da /api/stats il 1 novembre 2026. La cifra viene da una query all’endpoint, non da una stima: conta i record pubblicati e non dice quanti usino questa API correttamente.

## Cosa cambia e cosa no

La funzione non diventa più veloce: cambia solo l’identità. React confronta il riferimento con quello del render precedente e riusa il vecchio se le dipendenze sono uguali. Il corpo viene rieseguito a ogni chiamata, come prima.

## I tre casi in cui paga

## Il caso reale: ricerca con debounce

function Search({ onQuery }) { const [input, setInput] = useState(""); const commit = useCallback((value) => onQuery(value), [onQuery]); useEffect(() => { const id = setTimeout(() => commit(input), 250); return () => clearTimeout(id); }, [input, commit]); return ( setInput(event.target.value)} /> ); }

Senza useCallback, commit sarebbe una funzione nuova a ogni render e l’effect si riavvierebbe a ogni tasto, azzerando il timer prima che scada. Con la dipendenza stabile il timer parte una volta per valore digitato.

## Il rumore

Avvolgere ogni handler in useCallback con dipendenze vuote aggiunge una lista da mantenere e nasconde le variabili che la funzione legge: se il corpo usa input senza dichiararlo, il valore resta quello del primo render. Il guadagno è nullo finché nessuno confronta quell’identità.

## Verificare le dipendenze

npm install --save-dev eslint eslint-plugin-react-hooks npx eslint src

La regola react-hooks/exhaustive-deps del plugin, con licenza MIT, elenca le dipendenze mancanti; è un avviso e non una correzione automatica. A volte la risposta giusta è togliere il useCallback, non aggiungere la dipendenza.

## Record vivi nel catalogo

Un caso concreto è filters, dove i gestori di cambio passano a componenti figli, e expandable-tabs, dove la callback di cambio tab attraversa un componente memo. Il resto sta tra i 111.985 componenti e i 1.556 blocchi.

## La limitazione

useCallback non riduce il lavoro del browser: se il figlio non è memoizzato e l’identità non finisce in una lista di dipendenze, la funzione viene ricreata e confrontata senza alcun vantaggio. Il costo è una lista di dipendenze in più da tenere corretta a mano.

## Dove continuare

Il componente che beneficia della funzione stabile è in React.memo; le regole che il linter controlla sono in regole degli hook; il confronto con l’altro framework diffuso è in Vue 3 vs React.

## FAQ

### useCallback e useMemo: quale usare?

useMemo conserva un valore calcolato, useCallback conserva una funzione. Se il risultato è una funzione, useCallback è la forma abbreviata di useMemo con una funzione dentro.

### Posso usare useCallback senza dipendenze?

Sì, con un array vuoto la funzione resta la stessa per tutta la vita del componente. È corretto solo se il corpo non legge props o stato: altrimenti cattura i valori del primo render e resta fermo.

### useCallback rende il codice più veloce?

No. Il corpo viene eseguito a ogni chiamata come prima; cambia solo il riferimento della funzione. La velocità arriva dal componente che smette di ri-renderizzarsi perché l’identità è stabile.

### Serve useCallback con il compilatore di React?

Molto meno. Il compilatore applica la memoizzazione automatica e conserva le identità dove serve, quindi l’uso manuale resta per i casi che una misura ha dimostrato lenti.

### Perché la mia funzione cambia ancora a ogni render?

Perché una dipendenza nella lista è instabile: un oggetto creato nel render, una prop che cambia o un’altra funzione non memoizzata. Finché quella dipendenza cambia, useCallback restituisce una funzione nuova.
