React
key: la strategia che evita bug
La key è l’identità di un elemento nella lista: legala al dato, mai all’indice, e diventa anche il modo esplicito per azzerare lo stato di un componente.
In sintesi
- La key dice a React quale elemento è quale fra due render.
- L’indice come key attacca lo stato alla posizione, non al dato.
- Una key generata nel render rimonta il componente a ogni passaggio.
- Cambiare key azzera lo stato: è un reset esplicito, non un effetto collaterale.
La key è l’identità di un elemento nella lista: legala al dato e non all’indice, e diventa anche il modo esplicito per azzerare lo stato di un componente quando cambia il soggetto.
Cosa fa React con la key
Fra due render React confronta i figli per key: stessa key significa stesso elemento, quindi React riusa il nodo e il suo stato. Senza key usa la posizione, e lo stato resta attaccato alla posizione invece che al dato.
Il caso che perde i dati
function TodoList({ items, onToggle }) {
return (
{items.map((todo, index) => (
onToggle(todo.id)} />
{todo.title}
))}
);
}
Cancella la prima riga e la casella di controllo resta spuntata sulla riga che prende il suo posto: la key non è cambiata, quindi React ha riusato il nodo. Con key={todo.id} il nodo segue il dato e la casella si sposta con lui.
Key stabile senza id
Una key generata nel render, con Math.random() o crypto.randomUUID(), cambia a ogni passaggio: React smonta e rimonta tutto, e il campo perde focus e testo. L’id si assegna quando il dato nasce, non quando viene disegnato.
// assign the id when the row is created, not while rendering
const withIds = (rows) => rows.map((row) => ({ ...row, id: crypto.randomUUID() }));
Azzera lo stato cambiando la key
Cambiare la key smonta il componente e lo ricrea: il form riparte dai valori iniziali e gli effetti si rieseguono. È il modo più corto per azzerare uno stato, e il costo è tutto ciò che l’utente aveva scritto.
Il comando
npm install --save-dev eslint eslint-plugin-react
npx eslint src
Il plugin eslint-plugin-react è distribuito con licenza MIT e segnala la key mancante durante il lint; una key instabile invece passa, e resta il caso pericoloso.
Record vivi nel catalogo
Tre record mostrano liste con identità: table, che usa l’id di riga, leads-data-table con righe selezionabili, e la categoria input per i campi dentro le righe.
La limitazione
La key non arriva come prop al componente, quindi non puoi leggerla dentro: serve solo a React per il confronto. E nessun linter distingue una key stabile da una key casuale, perché entrambe sono sintatticamente valide.
Dove continuare
L’avviso che React stampa in console è spiegato in key warning nelle liste; le liste lunghe sono in virtualizzazione; cosa può restare derivato è in stato derivato; il confronto fra framework è in confronto framework frontend.
Domande frequenti
Perché usare l’indice come key è rischioso?
Perché l’indice descrive la posizione, non il dato. Quando la lista cambia ordine o perde un elemento, React riusa il nodo sbagliato e lo stato resta sulla posizione.
Devo sempre avere un id?
Sì, prima o poi. Se il dato non arriva con un id, assegnalo quando lo crei: una combinazione di campi è una soluzione temporanea che si rompe con i duplicati.
Cambiare la key azzera lo stato?
Sì. Una key diversa smonta il componente e ne crea uno nuovo, quindi lo stato riparte dai valori iniziali e gli effetti si rieseguono.
Perché il campo perde il focus a ogni tasto?
Quasi sempre perché la key cambia a ogni render: un id casuale o un oggetto ricreato nella lista. La key deve restare la stessa per lo stesso dato.
La key si può leggere dentro il componente?
No. React la consuma per il confronto e non la passa come prop; se ti serve il valore, passalo con un altro nome.