前言
首先我們要先複習的就是React Basics,第一篇我要來複習的是 JSX,之所以沒有選擇官方文件上的第一篇Component,是因為我認為如果我連我現在在寫的東西都不知道他是什麼的話,我要怎麼跟人家說我會呢?
什麼是JSX
先破題,JSX是React 提供了一種語法糖,能讓我們在定義 React element 的結構時有著相當類似於撰寫 HTML 語法的體驗。
在還沒看過zet助教的鐵人賽文章時,我對JSX的理解就是官方文件上的:
JSX is a syntax extension for JavaScript that lets you write HTML-like markup inside a JavaScript file.
也就是說他只是JavaScript 的語法擴展,讓我們用類似HTML的方式去編寫。
但在查找資料時,會看到很多文章都是說:『JSX 是把 HTML 寫在 JavaScript 中』。
但這跟官方文件上的有些許的不一樣,因此我去看了助教的文章才真正的瞭解他到底是什麼。
以下內容節錄JSX 根本就不是在 JavaScript 中寫 HTML:
1 | // 以普通的呼叫 React.createElement() 來定義 React element |
上面這兩段code我們執行後會發現,使用JSX語法的code經過開發工具的自動轉換之後的React element居然會跟使用 React.createElement()
的結果是一樣的,因此透過這個案例我們可以知道,寫 JSX 語法其實就是在寫 React.createElement()
。
所以,JSX 語法的本質完完全全就是 React.createElement()
方法的呼叫。
它長得很像 HTML 語法只是因為它被刻意設計成模仿 HTML 語法的撰寫和開發體驗,但是與 HTML 在本質上完全是不同的東西!
JSX 規則
Return a single root element
在官方文件有提到,要從元件返回多個元素,請使用單個父標記將它們包裝起來(To return multiple elements from a component, wrap them with a single parent tag.)1
2
3
4
5
6
7
8<div>
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
</div>或是可以用 Fragment(它對事物進行分組,而不會在瀏覽器 HTML 樹中留下任何痕跡。),如果Fragment沒有需要傳入任何的 props 的話,可以使用更簡潔的替代語法 — 直接以空標籤名稱
來代表 Fragment 元素類型:1
2
3
4
5
6
7
8<>
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
</>之所以要這樣主要是因為一段 JSX 其實就是呼叫一次
React.createElement()
,它只會返回「一個 React element」做為結果。讓我們以樹狀結構的方式下去想,就會發現問題其實出在「樹狀資料結構只能有一個根節點」上,因此只要我們把原本想要放置在同層級的多個 React element 節點,以一個共同的父節點給包起來就可以了。Close all the tags
JSX 會要求標籤顯式關閉,就算是在 HTML 中可以只寫開標籤的元素也是一樣(例如<img>
)。1
2
3
4
5
6
7
8
9
10
11
12<>
<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>
</>因為當標籤沒有正確的閉合時,JSX transformer 就會沒有辦法解析這層的 React element 結束在哪裡,因此就會因為找不到對應的閉標籤而無法進行轉換。
camelCase
allmost of the things
寫在JSX中的屬性(attribute)會轉換成JS 物件裡的key,在React元件裡我們有時會需要將這些屬性存取成變數,因此屬性命名方式需依照JS的變數命名規則。(例如class 必須寫成className, for必須寫成HTMLFor)
❗但是像是aria-*, data-*等屬性則是遵照原本HTML寫的模式
在JSX中使用JS
JSX 讓我們可以使用類似於 HTML 的語法來定義 React element,但畢竟它不像 HTML 語法一樣是純粹的文字字串,因此當想要在JSX標記內使用JavaScript表達式 就要用大括號{ }
包起來,除了放回傳值的表達式也可以傳入變數、函式等等
你只能在 JSX 中以兩種方式使用大括號:
作為直接在 JSX 標籤內的文本,例如:
1
2
3
4
5有效的:
<h1>{name}'s To Do List</h1>
無效的:
<{tag}>Gregorio Y. Zara's To Do List</{tag}>作為緊跟在
=
符號之後的屬性src={avatar}
將讀取avatar
變數,但如果我是成這樣src="{avatar}"
則是會回傳字串{avatar}
有時候我們會在code裡面看到會使用{{ }}
,這個有2種可能:
JSX正在傳遞一個 object
1
person={{ name: "Hedy Lamarr", inventions: 5 }}
inline CSS styles
1
2
3
4
5
6<ul style={
{
backgroundColor: 'black',
color: 'pink'
}
}>