導入和導出組件

組件的神奇之處在於它們的可重用性:您可以創建由其他組件組成的組件。但是當您巢狀越來越多的組件時,通常將它們拆分到不同的檔案中會比較合理。這可以讓您的檔案易於瀏覽,並在更多地方重複使用組件。

您將學到

  • 什麼是根組件檔案
  • 如何導入和導出組件
  • 何時使用預設和命名導入和導出
  • 如何從一個檔案導入和導出多個組件
  • 如何將組件拆分到多個檔案中

根組件檔案

你的第一個組件 中,您創建了一個 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 移出根組件檔案是合理的。這將使它們在其他檔案中更具模組化和可重用性。您可以通過三個步驟移動組件

  1. **創建**一個新的 JS 檔案來放置組件。
  2. 從該檔案**導出**您的函式組件(使用**預設**或**命名**導出)。
  3. 在您將使用組件的檔案中**導入**它(使用相應的技術導入**預設**或**命名**導出)。

這裡, ProfileGallery 都已從 App.js 移到一個名為 Gallery.js 的新檔案中。現在您可以更改 App.js 以從 Gallery.js 導入 Gallery

import Gallery from './Gallery.js';

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

請注意此範例現在如何分解為兩個組件檔案

  1. Gallery.js:
    • 定義僅在同一個檔案中使用且未導出的 Profile 組件。
    • Gallery 組件導出為**預設導出**。
  2. App.js:
    • Gallery.jsGallery 導入為**預設導入**。
    • 將根組件 App 作為 預設匯出 (default export)。

注意事項

您可能會遇到省略 .js 副檔名的檔案,如下所示:

import Gallery from './Gallery';

React 可以使用 './Gallery.js''./Gallery',雖然前者更接近 原生 ES 模組 (native ES Modules) 的運作方式。

深入探討

預設匯出與命名匯出

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',它仍然會提供您相同的預設匯出。相反地,使用命名匯入時,名稱必須兩邊相符。這就是為什麼它們被稱為*命名*匯入!

如果檔案只匯出一個組件,人們通常使用預設匯出;如果匯出多個組件和值,則使用命名匯出。 無論您偏好哪種程式碼風格,請務必為您的組件函式和包含它們的檔案命名 meaningful 的名稱。不鼓勵使用沒有名稱的組件,例如 export default () => {},因為它們會使除錯更加困難。

從同一個檔案匯出和匯入多個組件

如果您只想顯示一個 Profile 而不是一個圖庫,該怎麼辦?您也可以匯出 Profile 組件。但是 Gallery.js 已經有一個*預設*匯出,而您不能有*兩個*預設匯出。您可以建立一個具有預設匯出的新檔案,或者您可以為 Profile 新增一個*命名*匯出。 一個檔案只能有一個預設匯出,但可以有多個命名匯出!

注意事項

為了減少預設匯出和命名匯出之間的潛在混淆,有些團隊選擇只堅持一種風格(預設或命名),或者避免在單個檔案中混合使用它們。選擇最適合您的方式!

首先,使用命名匯出(沒有 default 關鍵字)從 Gallery.js匯出 Profile

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

然後,使用命名匯入(使用大括號)將 ProfileGallery.js 匯入App.js

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

最後,從 App 組件中 渲染 <Profile />

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:
    • Gallery.js 中將 Profile 作為 名為 Profile 的命名匯入匯入。
    • Gallery.jsGallery 導入為**預設導入**。
    • 將根組件 App 作為 預設匯出 (default export)。

重點回顧

在本頁中,您學習了

  • 什麼是根組件檔案
  • 如何導入和導出組件
  • 何時以及如何使用預設和命名匯入和匯出
  • 如何從同一個檔案匯出多個組件

挑戰 1 1:
進一步拆分組件

目前,Gallery.js 導出(export)了 ProfileGallery 兩者,這有點令人混淆。

Profile 組件移到它自己的 Profile.js 檔案中,然後更改 App 組件,使其依序渲染 <Profile /><Gallery />

您可以使用預設導出或命名導出 Profile,但請確保在 App.jsGallery.js 中都使用相對應的導入(import)語法!您可以參考上面深入探討中的表格。

語法匯出語句匯入語句
預設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>
  );
}

在您使用一種導出方式使其正常運作後,請嘗試使用另一種導出方式使其也能正常運作。