Імпорт та експорт компонентів

Магія компонентів полягає в їхньому повторному використанні: ви можете створювати компоненти, які складаються з інших компонентів. Але якщо ви вкладаєте все більше і більше компонентів, часто буває доцільно розділити їх на різні файли. Це дозволяє зберігати файли простими для розуміння та повторно використовувати компоненти в більшій кількості місць.

You will learn

  • Що таке файл кореневого компонента
  • Як імпортувати та експортувати компонент
  • Коли використовувати дефолтні та іменовані імпорти та експорти
  • Як імпортувати та експортувати декілька компонентів з одного файлу
  • Як розділити компоненти на декілька файлів

Файл кореневого компонента

У Ваш перший компонент , ви створили компонент Profile та компонент Gallery, який його відображає:

function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3As.jpg"
      alt="Кетерін Джонсон (Katherine Johnson)"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Видатні вчені</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

Ці компоненти зараз знаходяться у файлі кореневого компонента з назвою App.js у цьому прикладі. Залежно від вашої конфігурації ваш кореневий компонент може бути в іншому файлі. Якщо ви використовуєте фреймворк з роутингом на основі файлів, як-от Next.js, ваш кореневий компонент буде різним для кожної сторінки.

Експорт та імпорт компонента

Що, якщо ви захочете змінити стартовий екран у майбутньому і розмістити там список наукових книг? Або розмістити всі профілі десь інде? Розумно було б витягнути компоненти Gallery і Profile з файлу кореневого компоненту. Це зробить їх більш модульними та дасть можливість повторно використовувати їх в інших файлах. Ви можете перемістити компонент за три кроки:

  1. Створіть новий JS файл, щоб помістити компоненти в нього.
  2. Експортуйте ваш функціональний компонент з цього файлу (використовуючи або дефолтний або іменований експорти).
  3. Імпортуйте його в файл, де ви будете використовувати цей компонент (використовуючи відповідну техніку імпорту для дефолтного або іменованого експортів).

Обидва компоненти Profile та Gallery були перенесені з App.js в новий файл під назвою Gallery.js. Тепер ви можете змінити App.js, щоб імпортувати Gallery з Gallery.js:

import Gallery from './Gallery.js';

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

Зверніть увагу, як цей приклад розбито на два файли компонентів:

  1. Gallery.js:
    • Визначає компонент Profile, який використовується лише в межах цього ж файлу і не експортується.
    • Експортує компонент Gallery як дефолтний експорт.
  2. App.js:
    • Імпортує Gallery як дефолтний імпорт з Gallery.js.
    • Експортує кореневий компонент App як дефолтний експорт.

Note

Можливо, ви зустрінете файли, які не мають розширення .js, як наприклад:

import Gallery from './Gallery';

Будь-який з варіантів, './Gallery.js' або './Gallery', працюватиме з React, хоча перший варіант ближчий до того, як працюють нативні ES модулі

Deep Dive

Дефолтний експорт vs іменований

Є два основних способи експортування значень у JavaScript: дефолтний та іменований експорти. До цього моменту в наших прикладах ми використовували тільки дефолтний експорт. Але ви можете використовувати один або обидва способи в тому ж файлі. У файлі може бути не більше одного дефолтного експорту, але можна мати стільки іменованих експортів, скільки ви бажаєте.

Default and named exports

Як ви експортуєте свій компонент, так вам потрібно його і імпортувати. Ви отримаєте помилку, якщо спробуєте імпортувати дефолтний експорт таким же чином, як й іменований експорт! Ця таблиця може допомогти вам зорієнтуватися:

СинтаксисВираз експортуВираз імпорту
Дефолтнийexport default function Button() {}import Button from './Button.js';
Іменованийexport function Button() {}import { Button } from './Button.js';

Коли ви робите дефолтний імпорт, ви можете використовувати будь-яке ім’я, яке вам подобається після import. Наприклад, ви можете написати import Banana from './Button.js', і ви все ще отримаєте той самий дефолтний експорт. Натомість, з іменованим імпортом ім’я повинно збігатися з обох боків. Тому вони називаються іменованими імпортами!

Люди часто використовують дефолтний експорт, якщо файл експортує тільки один компонент, і використовують іменований експорт, якщо файл експортує кілька компонентів та значень. Незалежно від того, який стиль написання коду вам подобається, завжди давайте змістовні назви функціям компонентів та файлам, які їх містять. Компоненти без імен, наприклад, export default () => {}, не рекомендується використовувати, оскільки це ускладнює процес налагодження коду.

Експорт та імпорт кількох компонентів з одного файлу

Що, якщо ви хочете показати лише один компонент Profile, а не галерею? Ви можете експортувати компонент Profile також. Але в Gallery.js вже є дефолтний експорт, і не можна мати два дефолтних експорти. Ви можете створити новий файл з дефолтним експортом або додати іменований експорт для Profile. Файл може мати тільки один дефолтний експорт, але може мати безліч іменованих експортів!

Note

Для того, щоб зменшити можливість плутанини між дефолтним та іменованим експортом, деякі команди вибирають використання лише одного стилю (дефолтного або іменованого), або уникнення їх змішування в одному файлі. Робіть так, як вам зручно!

Спочатку, експортуйте Profile з Gallery.js, використовуючи іменований експорт (без ключового слова default):

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

Потім, імпортуйте Profile з Gallery.js в App.js, використовуючи іменований імпорт (з фігурними дужками):

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

Нарешті, відрендеріть компонент <Profile /> з компоненту App:

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

Тепер в Gallery.js знаходяться два експорти: дефолтний експорт Gallery та іменований експорт Profile. App.js імпортує їх обох. Спробуйте змінити <Profile /> на <Gallery /> та навпаки у цьому прикладі:

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

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

Тепер ви використовуєте комбінацію дефолтного та іменованого експортів:

  • Gallery.js:
    • Експортує компонент Profile як іменований експорт з назвою Profile.
    • Експортує компонент Gallery як дефолтний експорт.
  • App.js:
    • Імпортує Profile як іменований імпорт з назвою Profile із Gallery.js.
    • Імпортує Gallery як дефолтний імпорт з Gallery.js.
    • Експортує кореневий компонент App як дефолтний експорт.

Recap

На цій сторінці ви дізналися:

  • Що таке файл кореневого компонента
  • Як імпортувати та експортувати компонент
  • Коли і як використовувати дефолтні та іменовані імпорти та експорти
  • Як імпортувати та експортувати декілька компонентів з одного файлу

Challenge 1 of 1:
Розбити компоненти на менші частини

Зараз Gallery.js експортує як Profile, так і Gallery, що дещо заплутує розуміння.

Перенесіть компонент Profile у окремий файл Profile.js, а потім змініть компонент App так, щоб він рендерив <Profile /> та <Gallery /> один за іншим.

Ви можете використовувати як дефолтний, так і іменований експорт для Profile, проте переконайтеся, що використовуєте відповідний синтаксис імпорту як в App.js, так і в Gallery.js! Ви можете скористатися таблицею з розділу про поглиблений аналіз вище:

СинтаксисВираз експортуВираз імпорту
Дефолтнийexport default function Button() {}import Button from './Button.js';
Іменованийexport function Button() {}import { Button } from './Button.js';
// Перенесіть мене у 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>Видатні вчені</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

Після того, як зробите цей приклад робочим з одним типом експорту, зробіть це з іншим типом.