本篇筆記摘錄自官方文件 Writing Markup with JSX
JSX 是一種 JavaScript 的擴充語法 ( syntax extension ) ,使我們可以在 JavaScript 檔案中使用像是 HTML ( HTML-like ) 的標記式語言。
雖然也可以使用其他方式來撰寫元件 ( component ),但大部分的 React 開發者都會選擇使用簡明的 JSX 來撰寫。
JSX:Putting markup into JavaScript
網頁是由 HTML、CSS、JavaScript 所組成,過去長年以來,開發者都是分開進行撰寫,HTML 負責內容、CSS 負責樣式、JavaScript 負責互動邏輯,而這些行為通常是分開在不同的檔案裡進行:
當網頁的互動性變得越來越高,透過邏輯來決定的內容也跟著增加,本來由 HTML 負責顯示的內容 ,轉變由 JavaScript 負責,這就是為什麼 React 要將邏輯 ( logic ) 與標記式語言 ( markup ) 同時放在元件中。
以 button 為例,在同一個地方渲染邏輯與標記式語言,可確保它們在每次編輯時同步。
相對地,當兩者之間沒有關聯,像是 button 與 sidebar 的標記式語言,將它們各自獨立編輯,也會相對安全。
每一個 React 元件都是一個 JavaScript 的函式,裡面可能會包含一些標記式語言,用來渲染畫面。
React 使用名為 JSX 的擴充語法來當它的標記式語言,JSX 雖然與 HTML 看起來非常相似,但它的限制較為嚴格,並且可以顯示動態資訊。
Note
JSX 與 React 常常一起使用,但它們是各自獨立的東西,也可以分開使用。
JSX 是一種擴充語法,React 則是一個 JavaScript 的函式庫 ( library )。
Converting HTML to JSX
假設我們現在有一段 HTML 如下:
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
<li>Invent new traffic lights
<li>Rehearse a movie scene
<li>Improve the spectrum technology
</ul>
我們想將它放進我們的元件:
export default function TodoList() {
return (
// ???
)
}
如果直接將內容複製貼上過去,是沒有辦法成功執行的:
( 將左側拉桿向右移動,可以看見程式碼的部分,拉開後點擊左上角三條線漢堡圖示可以看見完整檔案,右邊則為輸出結果。 )
這是因為 JSX 在一些規則上比 HTML 嚴格,你可以閱讀上面的錯誤訊息,它將引導我們修正標記式語言的部分。
Note
在大多數的時候,React 所顯示的錯誤訊息都可以引導我們解決問題。
The Rules of JSX
1 . Return a single root element
要在元件中回傳多個元素時,需要用一個父標籤 ( parent tag ) 來包覆它們。
例如使用<div>
:
<div>
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
...
</ul>
</div>
如果不想要有多餘的<div>
標籤,我們也可以使用<>...</>
來包覆:
<>
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
...
</ul>
</>
這個空標籤稱為 Fragment,它可以包覆你的程式碼,並且不在 HTML tree 中留下痕跡。
【 Deep Dive 】
Why do multiple JSX tags need to be wrapped?
JSX 雖然看起來與 HTML 非常相似,實際上它會被轉換成 JavaScript 物件,你不可以在沒有包覆的情形下,同時在一個函式裡 return 兩個物件。
2 . Close all the tags
JSX 需要明確地關閉。
如果是自閉標籤 ( self-closing tags ),像是<img>
,必須改為<img />
。
如果是<li>oranges
,則需改為<li>oranges</li>
。
範例如下:
<>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
/>
<ul>
<li>Invent new traffic lights</li>
<li>Rehearse a movie scene</li>
<li>Improve the spectrum technology</li>
</ul>
</>
3 . camelCase most of the things!
JSX 會轉變為 JavaScript 物件,在 JSX 中的屬性 ( attributes ) 會變成 JavaScript 物件的 keys。
因此必須遵守 JavaScript 的命名規則,像是以 camelCase 命名,不能使用 dash,不能使用預設保留的詞,像是class
,在 JSX 中要改為className
。
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
className="photo"
/>
【 Pitfall 】
因為一些原因,
aria-*
與data-*
屬性依舊使用 dash 表示。