【 React 】JSX 是什麼?

Jamie Lo
6 min readDec 25, 2022

--

Photo by Jamie Street on Unsplash

本篇筆記摘錄自官方文件 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 表示。

Pro-tip: Use a JSX Converter

將已經寫好的 HTML 轉變為 JSX 寫法是一件麻煩的事,因此 React 官方推薦使用 converter,透過 converter 來轉換你的 HTML 與 SVG 到 JSX。

以下為轉換後的程式碼:

--

--

Jamie Lo

正在往前端這個知識量爆炸的黑洞前行,內容多為平時的筆記整理,希望也能幫助到同樣在這條道路上前進的人💪