React

children come prop: lo slot implicito

children è una prop come le altre, con una posizione fissa nel markup: React la riempie dal contenuto dell’elemento e il componente decide dove mostrarla.

In sintesi

  • JSX traduce il contenuto dell’elemento nella prop children, non in un canale separato.
  • Il tipo corretto è ReactNode, che include stringhe, numeri, null e array.
  • Uno spread di props che contiene children sostituisce in silenzio i figli già presenti.

children è una prop come le altre, con una posizione fissa nel markup: React la riempie con il contenuto dell’elemento e il componente decide dove mostrarla.

Dove nasce il valore

<Panel>testo</Panel> diventa createElement(Panel, null, "testo"), e il terzo argomento arriva in props.children. Scrivere children="testo" produce lo stesso risultato: cambia la sintassi, non il dato.

Il tipo giusto

In TypeScript il tipo è ReactNode, non string e non JSX.Element: accetta testo, numeri, null, frammenti e array di nodi.

type PanelProps = {
  title: React.ReactNode;
  children: React.ReactNode;
};

function Panel({ title, children }: PanelProps) {
  return (
    
      {title}
      {children}
    
  );
}

Con string il componente rifiuta un elemento; con JSX.Element rifiuta il testo. ReactNode è l’unione che corrisponde a ciò che React accetta davvero in un contenitore.

Più di uno slot

Quando le zone sono due o tre, i nomi espliciti battono children: header e footer si leggono nel punto di chiamata e non dipendono dall’ordine.

function Card({ header, children, footer }) {
  return (
    
      {header && {header}}
      {children}
      {footer && {footer}}
    
  );
}

children resta lo slot senza nome, quello che il chiamante riempie senza pensarci. Tutto il resto prende un nome, perché un nome è documentazione gratuita nel punto di uso.

L’errore silenzioso

Un componente che fa <div {...props} /> e poi <div>{children}</div> rompe le cose in due modi: lo spread porta dentro anche la prop children, che sostituisce i figli già presenti, e il secondo contenitore resta vuoto. Il tipo non aiuta, perché entrambe le forme sono valide.

Il comando

Il controllo dei tipi su children si fa con TypeScript; il comando installa i tipi di React e verifica il progetto senza emettere file.

npm install --save-dev typescript @types/react
npx tsc --noEmit

Tre record che usano children come contenuto: dialog riceve il corpo del modale, nested-dialog annida un secondo dialogo dentro il primo, accordion-05 mette un elemento per pannello. Sono record fra i 111.985 componenti del catalogo.

Fonte e licenza

React e @types/react sono distribuiti con licenza MIT. La pagina della documentazione React che spiega come passare le props descrive children come una prop normale, e il TypeScript cheatsheet indica ReactNode per i figli.

La limitazione

Il tipo non obbliga a passare qualcosa: children: React.ReactNode accetta anche undefined, quindi un pannello vuoto compila e produce un contenitore senza contenuto. Se il contenuto è obbligatorio serve un controllo a runtime o un tipo più stretto.

Dove continuare

Il modello generale è in che cos’è React; perché un children identico evita un render è in React.memo; il confronto con gli snippet di Svelte 5 è in snippet di Svelte 5.

Domande frequenti

children è obbligatorio?

No, a meno che il tipo non lo richieda. React passa undefined quando l’elemento non ha contenuto, quindi il componente deve gestire quel caso o dichiarare la prop come obbligatoria.

Posso leggere children come un array?

Non direttamente: children può essere un nodo singolo, una stringa o un array. Per contarlo o mapparlo si usa React.Children.toArray, che normalizza le forme.

Passare children a un elemento annidato è sbagliato?

No, è il modo normale di costruire un wrapper: il componente riceve i figli e li colloca dove serve. Diventa un errore quando uno spread di props li sovrascrive senza che nessuno se ne accorga.

Che differenza c’è fra children e prop children?

Nessuna: JSX riempie la prop children con il contenuto dell’elemento. Scrivere children={...} esplicitamente è equivalente e utile quando il valore è una variabile.

Un cambio di children rimonta il componente?

No, aggiorna la prop e React riconcilia i figli. Il sottoalbero si rimonta solo se cambia il tipo di elemento o la key.