Component 的神奇之處在於它的可複用性:你可以建立 component 並與其他 component 組合。但當你嵌套越來越多 component,則需要開始將它們拆分為不同的檔案。這將會提升檔案的閱讀性,也能讓 component 重複應用在更多地方。
You will learn
- 什麼是 root component 檔案
- 如何 import 和 export 一個 component
- 何時使用 default 和 named import 和 export
- 如何從一個檔案 import 和 export 多個 component
- 如何將 component 拆分為多個檔案
Root component 檔案
在你的第一個 Component 中,你建立了一個 Profile component,並且 render 在 Gallery component 裡:
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> ); }
在此範例中,目前所有的 component 都定義在名為 App.js 的 root component 檔案中。根據你的配置,root component 可能會位於其他檔案中。如果你使用像是 Next.js 這種路由基於檔案路由的框架,每個頁面的 root component 都會不一樣。
Exporting 和 importing 一個 component
如果將來你想要改變首頁,在此頁面放入科學書籍列表,或者需要將所有的資料移至其他檔案中。將 Gallery 以及 Profile 移出 root component 檔案會更加合理。這將會使它們更加模組化,並且可以在其他檔案中複用。你可以透過以下三個步驟拆分 component:
- 建立 一個新的 JS 檔案來存放該 component。
- Export 該檔案中的 component 函式(可以使用 default 或 named export)。
- 在需要使用該 component 的檔案中 import(可以根據相應的 import 方式使用 default 或 named export)。
這裡將 Profile 與 Gallery 從 App.js 檔案中移出,並放入一個名為 Gallery.js 的新檔案中。現在,你可以在 App.js import Gallery.js 中的 Gallery:
import Gallery from './Gallery.js'; export default function App() { return ( <Gallery /> ); }
請注意此範例是如何將 component 拆分為兩個檔案:
Gallery.js:- 定義了
Profilecomponent,該 component 僅在同個檔案中使用,並沒有被 export。 - 使用 default export 的方式,export
Gallerycomponent。
- 定義了
App.js:- 使用 default import 的方式,從
Gallery.jsimportGallery。 - 使用 default export 的方式,export root component
App。
- 使用 default import 的方式,從
Deep Dive
JavaScript 有兩種主要用來 export 值的方式:default export 以及 named export。 目前為止,我們的範例只有用到 default export。但你可以在同一個檔案中,選擇使用其中一種,或者兩種都使用。一個檔案中僅能有一個 default export,但可以有多個 named export。
Component 的 export 方式決定了其 import 方式。當你試著用 default export,import named export 的 component 將會報錯!下方圖表可以幫助你更好地理解它們:
| 語法 | Export 陳述 | Import 陳述 |
|---|---|---|
| Default | export default function Button() {} | import Button from './Button.js'; |
| Named | export function Button() {} | import { Button } from './Button.js'; |
當使用 default import 時,你可以在 import 後使用任意命名。例如 import Banana from './button.js',你仍舊可以獲取一致的預設 export 內容。相反地,對於 named import,import 與 export 的名稱必須一致。這也是為什麼它們被稱為 named import!
當檔案中只需要 export 一個 component 時,人們通常會使用 default export,當檔案包含多個 component 或值需要 export 時,則會使用 named export。無論你偏好哪種方式,請記得給予 component 以及對應檔案一個有意義的命名。不建議使用未命名的 component,像是 export default () => {},這將導致除錯變得困難。
從同一檔案 export 及 import 多個 component
如果你只想要顯示一個 Profile,而非整個圖集。你也可以 export Profile component。但是 Gallery.js 已經包含 default export,你不能有兩個 default export。你可以建立一個新檔案以進行 default export,或是你可以將 Profile 進行 named export。同一檔案只能有一個 default export,但可以有多個 named export!
首先,使用 named export 的方式,將 Profile 從 Gallery.js export(不使用 default 關鍵字):
export function Profile() {
// ...
}接著,使用 named import 的方式,從 Gallery.js import Profile 至 App.js(使用大括號):
import { Profile } from './Gallery.js';最後,在 App component 中 render <Profile />:
export default function App() {
return <Profile />;
}現在 Gallery.js 包含兩個 export:一個是 default export 的 Gallery,一個是 named export 的 Profile。App.js 都 import 了它們。請試著將下方範例中的 <Profile /> 改為 <Gallery />:
import Gallery from './Gallery.js'; import { Profile } from './Gallery.js'; export default function App() { return ( <Profile /> ); }
現在,你混合使用了 default export 以及 named export:
Gallery.js:- 使用 named export 的方式,export
Profilecomponent,並命名為Profile。 - 使用 default export 的方式,export
Gallerycomponent。
- 使用 named export 的方式,export
App.js:- 使用 named import 的方式,從
Gallery.jsimportProfile,並命名為Profile。 - 使用 default import 的方式,從
Gallery.jsimportGallery。 - 使用 default export 的方式,export root component
App。
- 使用 named import 的方式,從
Recap
在本章節中,你學到了:
- 什麼是 root component 檔案
- 如何 import 和 export 一個 component
- 何時以及如何使用 default 和 named import 和 export
- 如何將 component 拆分為多個檔案
Challenge 1 of 1: 進一步拆分 component
現在,Gallery.js 同時 export 了 Profile 與 Gallery,這會讓人感到有些混淆。
試著將 Profile component 移至 Profile.js,然後更新 App component,依序 render <Profile /> 與 <Gallery />。
你可能會使用 default export 或 named export 的方式來 export Profile,但請確保在 App.js 與 Gallery.js 中使用了相對應的 import 語法!具體方法可參考下方表格:
| 語法 | Export 陳述 | Import 陳述 |
|---|---|---|
| Default | export default function Button() {} | import Button from './Button.js'; |
| Named | 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> ); }
當你成功使用其中一種 export 方式時,請嘗試使用另一種方法實現。