コンポーネントのインポートとエクスポート

コンポーネントの魔法は、その再利用可能性にあります。他のコンポーネントで構成されるコンポーネントを作成できます。しかし、コンポーネントをどんどん入れ子にしていくと、異なるファイルに分割し始めることがよくあります。これにより、ファイルを簡単にスキャンし、複数の場所でコンポーネントを再利用できます。

学習内容

  • ルートコンポーネントファイルとは何か
  • コンポーネントのインポートとエクスポートの方法
  • デフォルトインポートと名前付きインポート、およびエクスポートを使用する場合
  • 1つのファイルから複数のコンポーネントをインポートおよびエクスポートする方法
  • コンポーネントを複数のファイルに分割する方法

ルートコンポーネントファイル

最初のコンポーネント」では、Profileコンポーネントと、それをレンダリングするGalleryコンポーネントを作成しました。

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

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

これらは現在、ルートコンポーネントファイル(この例では App.js)に格納されています。ただし、設定によっては、ルートコンポーネントは別のファイルにある可能性があります。Next.jsなどのファイルベースのルーティングを使用するフレームワークを使用する場合、ルートコンポーネントはページごとに異なります。

コンポーネントのエクスポートとインポート

将来、ランディング画面を変更して科学書のリストをそこに配置したい、またはすべてのプロファイルを別の場所に配置したい場合はどうでしょうか?GalleryProfileをルートコンポーネントファイルから移動することが理にかなっています。これにより、それらはよりモジュール化され、他のファイルで再利用できるようになります。コンポーネントは3つのステップで移動できます。

  1. 作成:コンポーネントを配置する新しいJSファイルを作成します。
  2. エクスポート:そのファイルから関数コンポーネントをエクスポートします(デフォルトまたは名前付きエクスポートを使用)。
  3. インポート:コンポーネントを使用するファイルにインポートします(デフォルトまたは名前付きインポートに対応する手法を使用)。

ここでは、ProfileGalleryの両方がApp.jsからGallery.jsという新しいファイルに移動されました。これで、Gallery.jsからGalleryをインポートするようにApp.jsを変更できます。

import Gallery from './Gallery.js';

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

この例がどのように2つのコンポーネントファイルに分割されているかに注目してください。

  1. Gallery.js:
    • Profileコンポーネントを定義します。これは同じファイル内でのみ使用され、エクスポートされません。
    • Galleryコンポーネントをデフォルトエクスポートとしてエクスポートします。
  2. App.js:
    • Gallery.jsからデフォルトインポートとしてGalleryをインポートします。
    • ルートAppコンポーネントをデフォルトエクスポートとしてエクスポートします。

注記

ファイル拡張子.jsを省略したファイルに出くわす場合があります。

import Gallery from './Gallery';

'./Gallery.js'または'./Gallery'のどちらでもReactでは機能しますが、前者の方がネイティブESモジュールの動作に近いです。

詳細解説

デフォルトエクスポートと名前付きエクスポート

JavaScriptで値をエクスポートする主な方法は2つあります。デフォルトエクスポートと名前付きエクスポートです。これまでの例では、デフォルトエクスポートのみを使用していました。しかし、同じファイルで両方を使用することもできます。1つのファイルには、デフォルトエクスポートは1つまでしか存在できませんが、名前付きエクスポートはいくつでも可能です。

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'と記述しても、同じデフォルトエクスポートが提供されます。対照的に、名前付きインポートでは、両側の名前が一致する必要があります。そのため、名前付きインポートと呼ばれます!

ファイルが1つのコンポーネントのみをエクスポートする場合はデフォルトエクスポートを、複数のコンポーネントと値をエクスポートする場合は名前付きエクスポートを使用することがよくあります。どちらのコーディングスタイルを好むかに関係なく、コンポーネント関数とそれを含むファイルには常に意味のある名前を付けましょう。export default () => {}のような名前のないコンポーネントは、デバッグを難しくするため、推奨されません。

同じファイルからの複数のコンポーネントのエクスポートとインポート

ギャラリーではなく、1つのProfileだけを表示したい場合はどうすればよいでしょうか?Profileコンポーネントもエクスポートできます。しかし、Gallery.jsには既にデフォルトエクスポートがあり、2つのデフォルトエクスポートを持つことはできません。デフォルトエクスポートを持つ新しいファイルを作成するか、Profile名前付きエクスポートを追加できます。1つのファイルにはデフォルトエクスポートを1つしか持つことができませんが、多数の名前付きエクスポートを持つことができます!

注記

デフォルトエクスポートと名前付きエクスポート間の混乱の可能性を減らすために、一部のチームは1つのスタイル(デフォルトまたは名前付き)のみに固執するか、単一のファイルでそれらを混在させることを避けています。自分に最適な方法を実行してください!

まず、名前付きエクスポート(defaultキーワードなし)を使用してGallery.jsからProfileエクスポートします。

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

次に、名前付きインポート(中括弧付き)を使用してGallery.jsからApp.jsProfileインポートします。

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

最後に、Appコンポーネントから<Profile />レンダリングします。

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

これで、Gallery.jsには、デフォルトのGalleryエクスポートと名前付きのProfileエクスポートの2つのエクスポートが含まれています。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:
    • Gallery.jsからProfileという名前付きインポートとしてProfileをインポートします。
    • Gallery.jsからデフォルトインポートとしてGalleryをインポートします。
    • ルートAppコンポーネントをデフォルトエクスポートとしてエクスポートします。

要約

このページでは、以下を学習しました。

  • ルートコンポーネントファイルとは何か
  • コンポーネントのインポートとエクスポートの方法
  • デフォルトインポートと名前付きインポート、およびエクスポートの使用方法と時期
  • 同じファイルから複数のコンポーネントをエクスポートする方法

課題 1 1:
コンポーネントをさらに分割する

現在、Gallery.jsProfileGallery の両方をエクスポートしており、やや分かりにくい状況です。

Profile コンポーネントを独自の Profile.js に移動し、その後、App コンポーネントを修正して、<Profile /><Gallery /> を続けてレンダリングするようにします。

Profile にはデフォルトエクスポートまたは名前付きエクスポートのいずれかを使用できますが、App.jsGallery.js の両方で対応するインポート構文を使用するようにしてください! 上記の詳細な説明にある表を参照してください。

構文エクスポート文インポート文
デフォルトexport default function Button() {}import Button from './Button.js';
名前付きexport 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>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

一方のエクスポート方法で動作を確認したら、もう一方の方法でも動作するようにしてください。