# React 19: il warning "A props object containing a key prop is being spread into JSX"

> Perché React 19 ora avvisa quando key finisce dentro un oggetto props spreadato, e come destrutturarla esplicitamente per risolvere.

- Autore / Author: Diego Betto (https://diegobetto.com/about/)
- Pubblicato / Published: 2026-10-12
- URL: https://diegobetto.com/react-19-key-spread-warning/
- Tag: react, 19, key, jsx, warning

Se sei appena passato a React 19 e hai iniziato a vedere questo warning in un punto dove non hai toccato `key` direttamente, vale la pena capirlo invece di ignorarlo:

> **Warning**
>
> A props object containing a "key" prop is being spread into JSX: {"<Component"} {"{"}...props{"}"}
> {" />"}. React keys must be passed directly to JSX without using spread. Learn more about keys:
> https://react.dev/link/warning-keys

È una novità di React 19 — le versioni precedenti ingoiavano silenziosamente `key` quando finiva dentro un oggetto spreadato, nascondendo un bug reale invece di farlo emergere. Capire perché `key` è speciale spiega la correzione.

## Perché `key` non può mai passare attraverso uno spread

`key` non è una prop normale. React la rimuove dall'oggetto props _prima_ che il tuo componente la veda mai — è metadata che React stesso usa per tracciare gli elementi di una lista tra i re-render, non qualcosa che la logica del tuo componente deve leggere via `props.key`. Questa distinzione conta qui:

```jsx
function List({ items }) {
  return items.map((item) => {
    const itemProps = { key: item.id, label: item.label };
    // key è dentro itemProps qui — ma React ha bisogno che sia sulla chiamata JSX stessa,
    // non sepolta dentro un oggetto spreadato
    return <Item {...itemProps} />;
  });
}
```

React legge `key` mentre elabora la chiamata `<Item ... />`, non ispezionando l'oggetto props finale che il tuo componente riceve — quindi una `key` nascosta dentro `...itemProps` non arriva mai dove React effettivamente la cerca. Nelle versioni precedenti di React questo produceva silenziosamente elementi di lista senza una key funzionante (vanificando la reconciliation di React per quella lista); React 19 rende visibile l'errore invece di nasconderlo.

## La correzione: destrutturare `key` esplicitamente

```jsx
function List({ items }) {
  return items.map((item) => {
    const { key, ...itemProps } = { key: item.id, label: item.label };
    return <Item key={key} {...itemProps} />;
  });
}
```

Oppure, più direttamente, evita di costruire un oggetto intermedio con `key` dentro e passa `key` sull'elemento JSX nel modo normale:

```jsx
function List({ items }) {
  return items.map((item) => <Item key={item.id} label={item.label} />);
}
```

## Dove si insinua: inoltrare props da un genitore

L'altro trigger comune è un componente che riceve una prop a forma di `key` da una risposta API o una struttura dati e spreada l'intero oggetto giù senza pensarci:

```jsx
function Row({ rowData }) {
  // rowData arriva da una API e ha per sue ragioni un campo `key`
  return <Cell {...rowData} />;
}
```

Se `rowData.key` non era affatto destinato a essere una React key — solo un campo dati che casualmente condivide il nome — rinominalo prima di spreadare, o destrutturalo fuori:

```jsx
function Row({ rowData }) {
  const { key, ...cellProps } = rowData;
  return <Cell {...cellProps} data-row-key={key} />;
}
```

> Se i tuoi dati arrivano davvero con un campo chiamato `key` per motivi non correlati (una colonna
> di database, un campo di una API esterna), è una collisione di nome che vale la pena risolvere a
> livello di dati se puoi — continuerà a far scattare questo warning (e a confondere i futuri
> lettori) ogni volta che quell'oggetto viene spreadato in JSX.

## FAQ

> **Era un bug silenzioso in React 18 e versioni precedenti?**
>
> Sì — `key` sepolta dentro un oggetto spreadato veniva silenziosamente scartata invece di essere
> applicata, quindi gli elementi di lista venivano renderizzati senza che React li tracciasse
> davvero con la key prevista. Spesso "funzionava" solo per caso, affidandosi al fallback di React
> che usa l'indice dell'array come key implicita.

> **Influisce sulla performance, non solo sulla correttezza?**
>
> Entrambe le cose. Una key mancante o basata sull'indice può far sì che React rimonti componenti
> inutilmente al riordino (perdendo lo stato locale, rieseguendo gli effect) invece di riusare il
> nodo DOM esistente — esattamente il problema che `key` esiste per prevenire.

> **Posso comunque spreadare altre props insieme a una key esplicita?**
>
> Sì, ed è il pattern standard e corretto: `<Item key={item.id} {...otherProps} />` — `key` passata
> direttamente, tutto il resto spreadato. Il warning scatta solo quando `key` stessa fa parte di ciò
> che viene spreadato.

## Conclusione

React 19 trasforma un bug che prima falliva silenziosamente — `key` ingoiata da uno spread — in un warning su cui puoi davvero agire. La correzione ha sempre la stessa forma: passa `key` direttamente sull'elemento JSX, mai come parte di un oggetto che spreadi con `{...props}`, e rinomina qualsiasi campo dati non correlato che casualmente collide con il nome `key` prima che arrivi al tuo JSX.

**Riferimenti**

- [Rendering lists and keys – documentazione React](https://react.dev/link/warning-keys)
- [Rules of keys – documentazione React](https://react.dev/learn/rendering-lists#rules-of-keys)
