元件 (Component) 是 React 的核心概念,不同的元件組成 UI,有點像拼樂高一樣。以往我們都說 HTML 是網頁的架構,再搭配 CSS 進行美化以及 JavaScript 添加互動功能,而 React 會將這些 HTML、CSS、JavaScript 組合成客製化的原件,小則按鈕、導覽列;大則整個網頁也能當成元件。
那元件能帶來什麼好處?
想像一下,一個部落格網站有成千上萬篇文章,而這些文章都有 UI 幾乎相同的目錄,如果把目錄獨立成元件,是不是便於管理和重複使用呢?
只要定義出一個元件,就可以用在其他不同的地方。
React 說到底就是個 JavaScript 的函式庫......或框架,所以每個元件都是 JavaScript 函式,函式裡面再帶入 HTML。再次注意這一切都在 JavaScript 運作,所以函式不會回傳單純的 HTML,而是 React 所提供的 JSX。
JSX 是 JavaScript 的語法擴充 (extension),目的誠如上述,為了讓我們在 JavaScript 檔案編寫近似 HTML 的標記 (markup)。補充一下,雖然 React 和 JSX 時常一起出現,但兩者彼此間是獨立的,也就是說,我們不用 JSX 也能寫 React,而 JSX 可以用在 React 以外的其他地方。
舉個 React 官網的例子逐步說明:
export default function Profile() {
return (
<img
src="https://i.imgur.com/MK3eW3Am.jpg"
alt="Katherine Johnson"
/>
)
}
透過關鍵字 export
來匯出元件,這是 JavaScript 的原生功能,並非 React 專屬的。至於 default
則代表匯出的東西,是這一份檔案的主要內容,使用 default 匯出,在別份檔案 import
時就可以使用任意名稱,無須遵循匯出時的內容名稱。每個檔案都只能有一個 export default
,詳情可以參考:
我們把函示名稱定為 Profile
,務必注意,React 元件雖然是 JavaScript 函式,但名稱開頭一定要大寫!若是小寫開頭,React 會試圖以 HTML 標記處理,而不會產生元件。
函式要回傳 JSX,所以 return
後面接上元件的 HTML 標記,如果全部內容塞成一行,可以不用包在小括號裡面,多行的話就需要。為了避免誤會,我覺得還是都用小括號包覆比較安全。
return (
<div>
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
</div>
);
前面提過元件的最大優勢在於重複利用。現在讓我們把元件嵌入在另一個元件裡面。
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>
);
}
非常淺顯易懂,我們在 Gallery
元件當中嵌入三個 Profile
元件,然後匯出 Gallery
。但要特別注意,元件被嵌入到其他元件的 JSX 中,還是要維持開頭字母大寫以利 React 區分一般的 HTML 標記和元件。
在這樣的語境下,Gallery
視為父層元件 (parent component),而 Profile
則是子層元件 (child component),與 HTML 的巢狀結構如出一轍。但瀏覽器畢竟不懂 JSX,所以最終還是要編譯成 HTML 才能渲染到瀏覽器上。上述程式碼會被轉為以下 HTML:
<section>
<h1>Amazing scientists</h1>
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
</section>
⛑️ 還有一件事情需要注意,雖然 Profile
是 Gallery
的子層元件,但千萬不要把它的定義函式寫在父層元件內!元件請獨立分開定義。