在上一篇學習筆記中,我們認識到了元件是 React 的核心概念,而元件的組成可以建立在另一個元件之上。我們當然可以把所有元件都放在根原件檔案中,就像上篇筆記的 App.js
。
// 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
將越來越肥大,落入難以管理和維護的窠臼。有鑑於此,React 引入了模組化的概念,將不同的元件拆分至獨立的檔案,並透過匯出、匯入的方式相互引用。
前面有提過,export
和 import
其實是 JavaScript 的原生方法。說來慚愧,之前學習 JavaScript 時並未好好了解這塊,剛好趁著這次機會彌補一下。
我們先把匯出與匯入的整體流程寫出來看看:
依循這樣的思路,把元件函式都移動到 Gallery.js
,App.js
就專心匯出最後的成果即可,當個稱職的根元件吧。因為元件都獨自成家了 (孩子們長得真快 🥹),別忘了在 App.js 透過關鍵字 import
來匯入另一份 JS 檔案。
// 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>
);
}
好的,道理我都懂,但馬上延伸出兩個問題:
default
打過電動都知道是預設的意思,但這邊到底在預設什麼?要解答以上疑惑,就要先看看 JavaScript 的 export
和 import
了。沒錯,過往不學好的報應來得總是又急又快,讓人措手不及。
簡單來說,export
分成兩種:
而 import
對應到 export
也有兩種,你大概已經猜到是哪兩種了:
我們先來認識一下 default
~
In JavaScript, a default export is a way to share a single value, function, or class as the main thing from a file with other parts of your code.
以一言以蔽之,default export
就是只匯出單一值、函式或 class,我們通常把匯出內容視為檔案中的「大菜」,畢竟都叫 default 了嘛,而且一份檔案僅能有一個 default export
。
由於其獨特性,在匯入 default import 時,我們無須在 import
後面加上大括號進行解構賦值。
// 📂 math.js
const add = (a, b) => a + b;
export default add;
// 📂 main.js
import myAddFunction from './math.js';
const result = myAddFunction(5, 10);
如果只想要匯出檔案中其中一個項目,請善用 named export
,只需要把 default 拿掉即可。至於 named import
就要特別留意了:
import
後面務必加上 { }
進行解構賦值麻煩歸麻煩,但除了可以只匯出/匯入特定項目,我們也能一次匯入多個 export
啊!所以別抱怨了,都給我解構起來。
// 📂 math.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
// 📂 main.js
import { add, subtract } from './math.js';
const result1 = add(5, 3); // result1 will be 8
const result2 = subtract(10, 4); // result2 will be 6
💡 default export
和 named export
可以在同份檔案一起使用。同時上主菜、小菜和甜點。
// 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>
);
}
當然由於這只是個簡單的案例,看起來難免有脫褲子放屁的感覺。但差別在於,現在 Profile
元件是用 named export
的方式從 Gallery.js
檔案匯出,所以它可以被匯入到其他任何檔案中,而不需要依存在 Gallery
元件內。
其實 export 和 import 還有其他值得玩味的地方,比方說透過 alias 為匯出/匯入的項目取名等等,日後有時間的話必定要回頭研究一下。底下附上參考資料: