Importazione ed Esportazione di Componenti

La magia dei componenti sta nella loro riutilizzabilità: si possono creare componenti che sono composti da altri componenti. Ma quando si annidano sempre più componenti, spesso ha senso iniziare a dividerli in file diversi. Ciò consente di mantenere i file facili da leggere e di riutilizzare i componenti in più punti.

Imparerai

  • Cos’è un file del componente radice
  • Come importare ed esportare un componente
  • Quando utilizzare importazioni ed esportazioni predefinite e nominali
  • Come importare ed esportare più componenti da un unico file
  • Come dividere i componenti in più file

Il file del componente radice

In Il Tuo Primo Componente, hai creato un componente Profile e un componente Gallery che lo renderizza:

function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Scienziati incredibili</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

Attualmente questi componenti si trovano nel file del componente radice, chiamato App.js in questo esempio. A seconda del tuo setup, il tuo componente radice potrebbe trovarsi in un altro file. Se stau utilizzando un framework con routing basato su file, come Next.js, il componente radice sarà diverso per ogni pagina.

Esportazione e importazione di un componente

E se in futuro si volesse cambiare la schermata di landing e inserire un elenco di libri scientifici? O mettere tutti i profili da qualche altra parte? Avrebbe senso spostare Gallery e Profile dal file radice del componente. Far questo renderà tali componenti più modulari e riutilizzabili in altri file. È possibile spostare un componente in tre fasi:

  1. Crea un nuovo file JS in cui inserire i componenti.
  2. Esporta la funzione del componente da quel file (utilizzando l’esportazione predefinita o nominale).
  3. Importa il componente nel file in cui lo si utilizzerà (utilizzando la tecnica corrispondente per l’importazione predefinita o nominale).

Qui sia Profile che Gallery sono stati spostati da App.js in un nuovo file chiamato Gallery.js. Ora si può modificare App.js per importare Gallery da Gallery.js:

import Gallery from './Gallery.js';

export default function App() {
  return (
    <Gallery />
  );
}

Si noti come questo esempio sia ora suddiviso in due file componenti:

  1. Gallery.js:
    • Definisce il componente Profile che viene utilizzato solo all’interno dello stesso file e non viene esportato.
    • Esporta il componente Gallery come esportazione predefinita.
  2. App.js:
    • Importa Gallery come importazione predefinita da Gallery.js.
    • Esporta il componente App principale come esportazione predefinita.

Nota bene

Si possono incontrare file che omettono l’estensione .js come in questo caso:

import Gallery from './Gallery';

Sia './Gallery.js' che './Gallery' funzioneranno con React, anche se il primo è più simile a come funzionano i Moduli ES nativi.

Approfondimento

Esportazioni predefinite o nominali

Esistono due modi principali per esportare valori in JavaScript: le esportazioni predefinite e le esportazioni nominali. Finora, i nostri esempi hanno utilizzato solo le esportazioni predefinite. Ma è possibile utilizzare una o entrambe nello stesso file. Un file non può avere più di un’esportazione default, ma può avere tutte le esportazioni nominali che si vogliono.

Esportazioni predefinite e nominali

Il modo in cui si esporta il componente determina il modo in cui lo si deve importare. Si otterrà un errore se si cerca di importare un’esportazione predefinita nello stesso modo in cui si importerebbe un’esportazione nominale! Questo grafico può aiutarti a non confonderti:

SintassiDichiarazione di esportazioneDichiarazione di importazione
Predefinitaexport default function Button() {}import Button from './Button.js';
Nominaleexport function Button() {}import { Button } from './Button.js';

Quando si utilizza un’importazione default, si può utilizzare qualsiasi nome si voglia dopo import. Per esempio, si potrebbe scrivere import Banana from './Button.js' e si otterrebbe comunque la stessa esportazione predefinita. Al contrario, con le importazioni nominali, il nome deve corrispondere da entrambe le parti. Ecco perché si chiamano importazioni nominali!

Spesso si utilizzano esportazioni predefinite se il file esporta un solo componente e esportazioni nominali se esporta più componenti e/o valori. Indipendentemente dallo stile che si preferisce, bisogna sempre dare nomi significativi alle funzioni dei componenti e ai file che li contengono. I componenti senza nome, come export default () => {}, sono sconsigliati perché rendono più difficile il debugging.

Esportazione e importazione di più componenti dallo stesso file

E se si volesse mostrare un solo Profile invece di una galleria? Si può esportare anche il componente Profile. Ma Gallery.js ha già un’esportazione default e non si possono avere due esportazioni predefinite. Si può creare un nuovo file con un’esportazione predefinita o aggiungere un’esportazione nominale per Profile. Un file può avere una sola esportazione predefinita, ma può avere numerose esportazioni nominali!

Nota bene

Per ridurre la potenziale confusione tra esportazioni predefinite e nominali, alcuni team scelgono di attenersi a un solo stile (predefinito o nominale) o di evitare di mescolarli in un unico file. Fai quello che funziona meglio per te!

Per prima cosa, esporta Profile da Gallery.js usando un’esportazione nominale (senza parola chiave default):

export function Profile() {
// ...
}

Quindi, importa Profile da Gallery.js in App.js usando un’importazione nominale (con le parentesi graffe):

import { Profile } from './Gallery.js';

Infine, renderizza <Profile /> nel componente App:

export default function App() {
return <Profile />;
}

Ora Gallery.js contiene due esportazioni: una predefinita Gallery e una denominata Profile. App.js le importa entrambe. Prova a modificare <Profile /> in <Gallery /> e viceversa in questo esempio:

import Gallery from './Gallery.js';
import { Profile } from './Gallery.js';

export default function App() {
  return (
    <Profile />
  );
}

Ora stai utilizzando un mix di esportazioni predefinite e nominate:

  • Gallery.js:
    • Esporta il componente Profile come un’esportazione nominale chiamata Profile.
    • Esporta il componente Gallery come esportazione predefinita.
  • App.js:
    • Importa Profile come un’importazione nominale chiamata Profile da Gallery.js.
    • Importa Gallery come importazione predefinita da Gallery.js.
    • Esporta il componente App principale come esportazione predefinita.

Riepilogo

In questa pagina hai imparato:

  • Cos’è un file del componente radice
  • Come importare ed esportare un componente
  • Quando e come utilizzare importazioni ed esportazioni predefinite e nominali
  • Come esportare più componenti dallo stesso file

Sfida 1 di 1:
Suddividere ulteriormente i componenti

Attualmente, Gallery.js esporta sia Profile che Gallery, il che crea un po’ di confusione.

Sposta il componente Profile nel proprio Profile.js, quindi modifica il componente App per renderizzare sia <Profile /> che <Gallery /> uno dopo l’altro.

Puoi usare un’esportazione predefinita o nominale per Profile, ma assicurati di usare la sintassi di importazione corrispondente sia in App.js che in Gallery.js! Puoi fare riferimento alla tabella di approfondimento di cui sopra:

SintassiDichiarazione di esportazioneDichiarazione di importazione
Predefinitaexport default function Button() {}import Button from './Button.js';
Nominaleexport function Button() {}import { Button } from './Button.js';
// Move me to Profile.js!
export function Profile() {
  return (
    <img
      src="https://i.imgur.com/QIrZWGIs.jpg"
      alt="Alan L. Hart"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Scienziati incredibili</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

Dopo aver fatto funzionare il tutto con un tipo di esportazioni, fallo funzionare con l’altro tipo.