コンポーネントの魔法は、その再利用可能性にあります。他のコンポーネントで構成されるコンポーネントを作成できます。しかし、コンポーネントをどんどん入れ子にしていくと、異なるファイルに分割し始めることがよくあります。これにより、ファイルを簡単にスキャンし、複数の場所でコンポーネントを再利用できます。
学習内容
- ルートコンポーネントファイルとは何か
- コンポーネントのインポートとエクスポートの方法
- デフォルトインポートと名前付きインポート、およびエクスポートを使用する場合
- 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などのファイルベースのルーティングを使用するフレームワークを使用する場合、ルートコンポーネントはページごとに異なります。
コンポーネントのエクスポートとインポート
将来、ランディング画面を変更して科学書のリストをそこに配置したい、またはすべてのプロファイルを別の場所に配置したい場合はどうでしょうか?GalleryとProfileをルートコンポーネントファイルから移動することが理にかなっています。これにより、それらはよりモジュール化され、他のファイルで再利用できるようになります。コンポーネントは3つのステップで移動できます。
- 作成:コンポーネントを配置する新しいJSファイルを作成します。
- エクスポート:そのファイルから関数コンポーネントをエクスポートします(デフォルトまたは名前付きエクスポートを使用)。
- インポート:コンポーネントを使用するファイルにインポートします(デフォルトまたは名前付きインポートに対応する手法を使用)。
ここでは、ProfileとGalleryの両方がApp.jsからGallery.jsという新しいファイルに移動されました。これで、Gallery.jsからGalleryをインポートするようにApp.jsを変更できます。
import Gallery from './Gallery.js'; export default function App() { return ( <Gallery /> ); }
この例がどのように2つのコンポーネントファイルに分割されているかに注目してください。
Gallery.js:Profileコンポーネントを定義します。これは同じファイル内でのみ使用され、エクスポートされません。Galleryコンポーネントをデフォルトエクスポートとしてエクスポートします。
App.js:Gallery.jsからデフォルトインポートとしてGalleryをインポートします。- ルート
Appコンポーネントをデフォルトエクスポートとしてエクスポートします。
詳細解説
JavaScriptで値をエクスポートする主な方法は2つあります。デフォルトエクスポートと名前付きエクスポートです。これまでの例では、デフォルトエクスポートのみを使用していました。しかし、同じファイルで両方を使用することもできます。1つのファイルには、デフォルトエクスポートは1つまでしか存在できませんが、名前付きエクスポートはいくつでも可能です。
コンポーネントのエクスポート方法は、インポート方法を決定します。デフォルトエクスポートを名前付きエクスポートと同じ方法でインポートしようとすると、エラーが発生します!この表は、追跡に役立ちます。
| 構文 | エクスポート文 | インポート文 |
|---|---|---|
| デフォルト | | |
| 名前付き | | |
デフォルトインポートを作成する際には、importの後に任意の名前を付けることができます。たとえば、import Banana from './Button.js'と記述しても、同じデフォルトエクスポートが提供されます。対照的に、名前付きインポートでは、両側の名前が一致する必要があります。そのため、名前付きインポートと呼ばれます!
ファイルが1つのコンポーネントのみをエクスポートする場合はデフォルトエクスポートを、複数のコンポーネントと値をエクスポートする場合は名前付きエクスポートを使用することがよくあります。どちらのコーディングスタイルを好むかに関係なく、コンポーネント関数とそれを含むファイルには常に意味のある名前を付けましょう。export default () => {}のような名前のないコンポーネントは、デバッグを難しくするため、推奨されません。
同じファイルからの複数のコンポーネントのエクスポートとインポート
ギャラリーではなく、1つのProfileだけを表示したい場合はどうすればよいでしょうか?Profileコンポーネントもエクスポートできます。しかし、Gallery.jsには既にデフォルトエクスポートがあり、2つのデフォルトエクスポートを持つことはできません。デフォルトエクスポートを持つ新しいファイルを作成するか、Profileの名前付きエクスポートを追加できます。1つのファイルにはデフォルトエクスポートを1つしか持つことができませんが、多数の名前付きエクスポートを持つことができます!
まず、名前付きエクスポート(defaultキーワードなし)を使用してGallery.jsからProfileをエクスポートします。
export function Profile() {
// ...
}次に、名前付きインポート(中括弧付き)を使用してGallery.jsからApp.jsにProfileをインポートします。
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.js は Profile と Gallery の両方をエクスポートしており、やや分かりにくい状況です。
Profile コンポーネントを独自の Profile.js に移動し、その後、App コンポーネントを修正して、<Profile /> と <Gallery /> を続けてレンダリングするようにします。
Profile にはデフォルトエクスポートまたは名前付きエクスポートのいずれかを使用できますが、App.js と Gallery.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> ); }
一方のエクスポート方法で動作を確認したら、もう一方の方法でも動作するようにしてください。