# Render props vs hooks: which one wins

The hook wins when you need only state and behaviour; the render prop wins when the markup must stay with the component that hosts it.

> Page: https://ui.eneawork.it/blog/react-render-props-vs-hooks
> Markdown: https://ui.eneawork.it/blog/react-render-props-vs-hooks.md

*2026-11-01*

Vince il hook nella maggior parte dei casi, perché restituisce stato e funzioni senza imporre markup; vince la render prop quando la struttura deve restare al componente che la ospita, come in una lista virtualizzata o in un grafico.

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 questo pattern correttamente.

## Cosa restituisce ciascuno

Il hook restituisce dati e callback, e il chiamante scrive il JSX. La render prop riceve una funzione che il componente chiama con i suoi dati, e quella funzione restituisce il JSX: il controllo della struttura passa dall’altra parte.

function useHover() { const [hovered, setHovered] = useState(false); const bind = { onMouseEnter: () => setHovered(true), onMouseLeave: () => setHovered(false), }; return { hovered, bind }; }

function Hover({ children }) { const [hovered, setHovered] = useState(false); const bind = { onMouseEnter: () => setHovered(true), onMouseLeave: () => setHovered(false), }; return children({ hovered, bind }); }

## La differenza in una tabella

## Quando la render prop è l’unica scelta

Quando la libreria possiede le misure: una lista virtualizzata conosce l’altezza delle righe, un grafico conosce gli assi, un drag and drop conosce le maniglie. Il chiamante non può riscrivere quel markup, quindi la funzione che riceve i dati è l’unico contratto sensato.

## Perché il hook ha vinto nei casi normali

Un hook non aggiunge un componente all’albero, non richiede una funzione nuova a ogni render e si compone con altri hook. Il tipo di ritorno si legge nella firma, e il test si scrive con renderHook senza montare nessun markup.

## L’errore che costa un render

Una funzione freccia scritta dentro il JSX cambia identità a ogni passaggio: se il componente è avvolto in memo, il confronto sulle props fallisce e il sottoalbero si ridisegna. Con il hook lo stesso problema esiste sulle dipendenze, ma si vede in un punto solo.

## Il comando

Per verificare entrambe le forme serve un test runner e una libreria di rendering; il comando installa i due pacchetti e lancia la suite.

npm install --save-dev vitest @testing-library/react npx vitest run

## Record vivi nel catalogo

Il catalogo contiene entrambe le forme: use-mouse-position-ref è un hook pubblicato come record, spotlight-card decide da sé il markup e riceve solo i contenuti, container-scroll-animation possiede la misura dello scroll. Sono record fra i 111.985 componenti.

## Fonte e licenza

React e @testing-library/react sono distribuiti con licenza MIT. La documentazione React tiene ancora una pagina dedicata alle render props proprio perché il pattern non è sparito: gli hook coprono i casi in cui il markup non è in gioco.

## La limitazione

Un hook non può restituire JSX, quindi una libreria che deve possedere il markup non può essere un hook: chi espone entrambe le forme costringe il chiamante a imparare due contratti e a scegliere senza un criterio unico.

## Dove continuare

Le regole di chiamata sono in regole degli hook; quando derivare lo stato evita del tutto l’effetto è in stato derivato; il confronto con i composable di Vue è in Composition API di Vue 3.

## FAQ

### Posso usare hook e render props nello stesso componente?

Sì, e in molti casi conviene: il hook gestisce lo stato, la render prop decide dove finisce il markup. L’importante è che la funzione passata sia stabile, altrimenti ogni render ne crea una nuova.

### Le render props sono deprecate?

No. React non le ha deprecate: le ha superate nei casi comuni, perché un hook fa la stessa cosa senza aggiungere un livello all’albero.

### Perché il hook non può restituire JSX?

Perché un hook è una funzione di dati, non di rendering: React lo chiama durante il render del componente e il JSX deve nascere da un componente. Restituire JSX da un hook confonde i due ruoli.

### Il test con renderHook basta?

Per lo stato e le callback sì. Se il componente che usa il hook ha un markup critico serve anche un test con Testing Library, perché il hook non vede il DOM.

### Meglio children o render prop?

children quando il contenuto è statico e il componente lo colloca; render prop quando il contenuto dipende da dati che il componente calcola, come l’indice di una riga o lo stato di hover.
