# React.memo: quando serve davvero

React.memo salta il re-render quando le props restano uguali, ma paga solo su componenti costosi con props stabili: altrove aggiunge confronti e memoria senza guadagno.

> Pagina: https://ui.eneawork.it/blog/react-memo-quando-serve
> Markdown: https://ui.eneawork.it/blog/react-memo-quando-serve.md

*2026-11-01*

React.memo avvolge un componente e salta il render quando le props sono uguali. Il confronto è superficiale, quindi paga su componenti costosi con props primitive e stabili, e altrove aggiunge lavoro.

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 confronta davvero

Il confronto è Object.is su ogni prop, una per una. Numeri, stringhe e booleani uguali fermano il render; un oggetto creato nel render del genitore ha una nuova identità a ogni passaggio, quindi il confronto fallisce sempre e il componente si ri-renderizza comunque.

## Il caso in cui paga

Una tabella con cinquanta righe e un campo di ricerca sopra: ogni tasto premuto ri-renderizza il genitore. Se la riga è memoizzata e riceve solo id e label, le righe che non cambiano non vengono ricalcolate.

const Row = memo(function Row({ id, label, onSelect }) { return ( onSelect(id)}> {label} ); });

La funzione onSelect però è una prop come le altre: se nasce nel render del genitore cambia identità a ogni giro e annulla il memo. Va stabilizzata con useCallback, oppure passata da un context che cambia raramente.

## Il caso in cui non paga

## Misurarlo prima di aggiungerlo

npm create vite@latest memo-demo -- --template react-ts cd memo-demo npm install npm run dev

Con l’app aperta, il Profiler di React DevTools registra i render per componente e mostra quanto dura ognuno. Aggiungi memo solo al componente che compare in cima alla lista con un tempo misurabile, non a tutti quelli che sembrano lenti.

## Record vivi nel catalogo

Due record adatti al test: table per una griglia con molte righe e list-item per una riga riutilizzabile. Il catalogo completo è tra i 111.985 componenti e le 12.808 icone.

## La limitazione

memo ferma solo i render che arrivano dal genitore. Uno stato interno che cambia, un context che cambia o una prop non stabile ri-renderizzano il componente lo stesso; e il confronto non è gratis, quindi sui componenti piccoli il rimedio costa più del problema.

## Dove continuare

La funzione stabile che serve al memo è in useCallback; il caso in cui il memo non aiuta è in context e performance; il confronto con un framework senza memo manuale è in Svelte vs React.

## FAQ

### React.memo è la stessa cosa di useMemo?

No. memo avvolge un componente e salta il suo render quando le props non cambiano; useMemo conserva il risultato di un calcolo dentro un componente. Servono a due problemi diversi.

### Quando il confronto superficiale non basta?

Quando una prop è un oggetto con molti campi e il genitore non può stabilizzarla. In quel caso si passa una funzione di confronto a memo, ma un confronto profondo costa quanto il render che vuoi evitare.

### memo funziona con i componenti di classe?

Sì. memo accetta qualsiasi componente, di classe o funzione, e restituisce un componente con il confronto sulle props. Non funziona invece sui valori: per quelli c’è useMemo.

### Serve ancora memo con il compilatore di React?

Molto meno. Il compilatore inserisce la memoizzazione automatica dove riconosce un guadagno, quindi il memo scritto a mano resta utile solo dopo una misura che mostra un componente ancora lento.

### Perché il mio componente memo continua a ri-renderizzarsi?

Quasi sempre per una prop con identità nuova a ogni render, oppure per un context che cambia. Controlla le props con il Profiler e verifica quali valori vengono ricreati nel genitore.
