React Doc | Describing the UI - Importing and Exporting Components

picture

2024-04-30

React Doc | Describing the UI - Importing and Exporting Components

前言

此為 Describing the UI: Unveiling the Power of React Components 此篇文章的延伸內容之一。

這一系列文章是筆者在學習 React 時,閱讀 React 官方文件 所做的翻譯筆記,希望能幫助更多的人學習 React。

本篇文章沒有節錄原文範例的輸出結果,如有需要請至原文對照參考。最後原文有提供一個實作的挑戰,這裡筆者就不放上來了,這部分請至原文按照步驟試試看。

導入與導出元件 (Importing and Exporting Components)

元件(Component)的魔力在於它們的可重複使用性:你可以建立由其他元件組成的元件。也就是說,一個元件中可以包含多個元件,一層又一層的嵌套下去。

但隨著嵌套元件越來越多,我們就越需要將它們拆分為不同的檔案、文件(File)。如此一來,我們的檔案會變得更方便瀏覽,並且可以在更多地方重複使用這些元件。

這章節你將會學到

  • 什麼是根元件檔案
  • 如何導入和導出一個元件
  • 何時使用預設和具名的導入和導出
  • 如何從一個文件中導入和導出多個元件
  • 如何將元件拆分為多個文件

根元件檔案 (The root component file)

Your First Component 中,你建立了一個 Profile 元件和一個 Gallery 元件來渲染它,這章節會接續這個範例,繼續示範:

App.js:

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

根據每個人自己的設定,根元件名稱不一定要是 App.js,而可能是 index.jsMain.js 等。總之,根元件檔案是你應用程式的入口點,通常包含應用程式的主要元件。

而如果你使用基於檔案路由的框架 (framework with file-based routing),例如 Next.js,則每個頁面的根元件都會不同。(這裡不會進一步說明有關 Next.js 的內容,有興趣的讀者可自行查閱 Next.js 官方文件

導出和導入元件 (Exporting and importing a component)

現在我們要將範例中的 GalleryProfile 從根元件檔案 (App.js) 中移出,因為我們可能會在其他地方重複使用它們。我們要盡量將元件拆分為更小的部分,這樣可以更容易維護和重複使用。

我們可以通過三個步驟移動這個元件:

  1. 首先先建立一個新的 JS 檔案以放置此元件。
  2. 從新的檔案中導出此函數元件,可以使用 預設導出 (default export) 或是 具名導出 (named export)
  3. 在要使用此元件的檔案中導入它。

現在將 ProfileGallery 兩者都從 App.js 移動到一個名為 Gallery.js 的新檔案中。

並且在 App.js 中設定,從 Gallery.js 導入 Gallery 元件:

App.js:

import Gallery from "./Gallery.js";

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

Gallery.js:

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>
  );
}

請注意,此範例現在分為兩個元件檔案:

  1. Gallery.js
    • 定義 Profile 元件,此元件僅在同一檔案中使用,並未導出。
    • Gallery 元件作為 預設導出 (default export)
  2. App.js
    • Gallery.js 中,將 Gallery 預設導入 (default import)。(意思就是 : 使用預設導入的方式導入)
    • 將根元件 App 作為 預設導出

筆記 :
你可能會遇到省略 .js 檔案副檔名的情況,像這樣:jsx import Gallery from "./Gallery"; 在 React 中,'./Gallery.js''./Gallery' 都可以使用,不過前者更接近 原生 ES 模組 的運作方式。

深入探討 : 預設導出 vs 具名導出 (Default vs named exports)

在 JavaScript 中,有兩種主要的導出值的方式:預設導出和具名導出。

到目前為止,我們的例子只使用了預設導出。但其實我們可以在同一個文件中使用其中一個,或者兩個都同時使用。

特別注意:一個文件最多只能有一個 預設 導出,但可以有任意多個 具名 導出。

i\_import-export

你導出元件的方式會決定你必須如何導入它。也就是說,如果你嘗試以與具名導出相同的方式導入預設導出,就會收到錯誤!

以下表格可以幫助你對照:

Syntax Export statement Import statement
Default export default function Button() {} import Button from './Button.js';
Named export function Button() {} import { Button } from './Button.js';

當你撰寫預設導入時,你可以在 import 後面放置任何你想要的名稱。例如,你可以寫成 import Banana from './Button.js',它仍然會提供你相同的預設導出。

相比之下,對於具名導入,名稱必須在兩側匹配。這就是為什麼它們被稱為 具名 導入的原因!

如果檔案只導出一個元件,人們通常會使用預設導出,如果檔案會導出多個元件和值,則會使用具名導出。

無論你偏好哪種程式碼風格都可以。比較需要注意的是,請將你的元件函式(component functions)以及包含元件的檔案,賦予有意義的命名。有意義的命名可以幫助你和其他人更容易理解你的程式碼。

這裡舉例一個有意義的命名方式:像是一個元件函式用來呈現按鈕的話,我們會命名為 Button,而包含此元件函式的檔案我們就會命名為 Button.js

注意,我們不建議你這樣寫這種沒有名稱的元件,例如 export default () => {},因為它們會使除錯變得困難。

從同一個文件導出和導入多個元件 (Exporting and importing multiple components from the same file)

如果我們要顯示 Profile 呢?

我們可以從 Gallery.js 導出 Profile 元件,但是目前 Gallery.js 已經有一個預設導出,並且一個檔案不能有兩個預設導出,所以我們只能使用具名導出 Profile 元件。

或者另一種方式是,我們可以將 Profile 元件移動到一個新的檔案中,例如 Profile.js,然後在 Gallery.js 中導入它。

筆記 :
為了減少預設導出和具名導出之間的潛在混淆,有一些團隊會選擇只使用一種風格(預設或具名),或者避免在單個文件中混合它們。請按照最適合你的方式操作!

這裡的範例是從 Gallery.js 導出 Profile 元件,並在 App.js 中導入它。

首先,在 Gallery.js 中使用具名導出 Profile(不使用 default ):

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

然後,在 App.js 中使用具名導入 Profile(使用大括號 {} ):

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

最後,在 App 元件中渲染 <Profile />

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

總之,現在 Gallery.js 檔案中包含兩個導出:一個是預設的 Gallery 導出,另一個是具名的 Profile 導出。並在 App.js 導入了它們兩個:

App.js :

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

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

Gallery.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>
  );
}

這個範例混合使用了預設導出和具名導出,這裡再做一個統整:

  • Gallery.js
    • Profile 元件作為 具名導出
    • Gallery 元件作為 預設導出
  • App.js
    • Gallery.js 中,將 Profile 具名導入
    • Gallery.js 中,將 Gallery 預設導入
    • 將根元件 App 作為 預設導出

試著挑戰看看 (Try out some challenges)

這部分是一個挑戰題,這裡僅翻譯題目,剩下答題的部分就去原文照著步驟挑戰看看吧!

題目 - 挑戰 1/1: 進一步拆分元件

目前,Gallery.js 同時導出了 ProfileGallery,這讓人有點混亂。

請將 Profile 元件移動到自己的 Profile.js 中,然後更改 App 元件以依次渲染 <Profile /><Gallery />

你可以為 Profile 使用預設導出或具名導出,但請確保在 App.jsGallery.js 中使用相應的導入語法!你可以參考上面深入探討中的表格:

Syntax Export statement Import statement
Default export default function Button() {} import Button from './Button.js';
Named export function Button() {} import { Button } from './Button.js';

結語

這篇文章帶我們了解到如何將元件拆分為不同的檔案,並在不同檔案之間導入和導出它們。

透過這樣拆分,把不同的元件放在不同的檔案中,可以讓我們更容易找到我們想要的元件,並且可以在需要的地方重複使用它們。

例如將 Button、SearchBar、Pagination、Card 等元件放在不同的檔案中,當我們需要使用時,只需要導入即可,不需要重複寫一次,這就是共用元件的好處。

重點回顧:

  1. 根元件檔案是一個包含多個元件的文件,通常是應用程式的入口點。(如果使用基於檔案路由的框架像是 Next.js,則每個頁面的根元件都會不同)
  2. 使用預設導出和具名導出來導出元件,並使用相應的導入語法來導入它們。
  3. 一個文件最多只能有一個預設導出,但可以有任意多個具名導出。

本文參考來源

Importing and Exporting Components

liz_avatar

Liz

軟體工程師

喜歡冷笑話和蒐集迷因。有點社交焦慮。在 MBTI 中連續多年的測試結果為 ISTP。最愛的活動是坐在沙發上和好朋友玩電動一整天。

查看作者的其他文章

分享到

回上頁