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

Software Engineer

A dad joke lover and meme collector. A bit socially anxious. Consistently testing as ISTP in the MBTI for several years. Favorite activity is spending the whole day playing video games on the couch with the best friends.

Check more from this author

Share to

Back