JSX 是 JavaScript 語法擴展,可以讓你在 JavaScript 文件中書寫類似 HTML 的標簽。雖然還有其它方式可以編寫組件,但大部分 React 開發者更喜歡 JSX 的簡潔性,并且在大部分代碼庫中使用它。
你將會學習到:
· 為什么 React 將標簽和渲染邏輯耦合在一起
· JSX 與 HTML 有什么區別
· 如何通過 JSX 展示信息
JSX: 將標簽引入 JavaScript
網頁是構建在 HTML、CSS 和 JavaScript 之上的。多年以來,web 開發者都是將網頁內容存放在 HTML 中,樣式放在 CSS 中,而邏輯則放在 JavaScript 中 —— 通常是在不同的文件中!頁面的內容通過標簽語言描述并存放在 HTML 文件中,而邏輯則單獨存放在 JavaScript 文件中。
但隨著 Web 的交互性越來越強,邏輯越來越決定頁面中的內容。JavaScript 控制著 HTML 的內容!這也是為什么 在 React 中,渲染邏輯和標簽共同存在于同一個地方——組件。
將一個按鈕的渲染邏輯和標簽放在一起可以確保它們在每次編輯時都能保持互相同步。反之,彼此無關的細節是互相隔離的,例如按鈕的標簽和側邊欄的標簽。這樣我們在修改其中任意一個組件時會更安全。
每個 React 組件都是一個 JavaScript 函數,它會返回一些標簽,React 會將這些標簽渲染到瀏覽器上。React 組件使用一種被稱為 JSX 的語法擴展來描述這些標簽。JSX 看起來和 HTML 很像,但它的語法更加嚴格并且可以動態展示信息。了解這些區別最好的方式就是將一些 HTML 標簽轉化為 JSX 標簽。
JSX and React 是相互獨立的 東西。但它們經常一起使用,但你 可以 單獨使用它們中的任意一個,JSX 是一種語法擴展,而 React 則是一個 JavaScript 的庫。
將 HTML 轉化為 JSX
假設你現在有一些(完全有效的)HTML 標簽:
<h1>海蒂·拉瑪的待辦事項</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
<li>發明一種新式交通信號燈
<li>排練一個電影場景
<li>改進頻譜技術
</ul>
而現在想要把這些標簽遷移到組件中:
export default function TodoList() {
return (
// ???
)
}
如果直接復制到組件中,并不能正常工作:
這是因為 JSX 語法更加嚴格并且相比 HTML 有更多的規則!上面的錯誤提示可以幫助你修復標簽中的錯誤,當然也可以參考下面的指引。
大部分情況下,React 在屏幕上顯示的錯誤提示就能幫你找到問題所在,如果在編寫過程中遇到問題就參考一下提示吧。
JSX 規則
1. 只能返回一個根元素
如果想要在一個組件中包含多個元素,需要用一個父標簽把它們包裹起來。
例如,你可以使用一個 <div>
標簽:
<div>
<h1>海蒂·拉瑪的待辦事項</h1>
<img src="https://i.imgur.com/yXOvdOSs.jpg" alt="Hedy Lamarr" class="photo" >
<ul> ... </ul>
</div>
如果你不想在標簽中增加一個額外的 <div>
,可以用 <>
和 </>
元素來代替:
<>
<h1>海蒂·拉瑪的待辦事項</h1>
<img src="https://i.imgur.com/yXOvdOSs.jpg" alt="Hedy Lamarr" class="photo" >
<ul> ... </ul>
</>
這個空標簽被稱作 Fragment。React Fragment 允許你將子元素分組,而不會在 HTML 結構中添加額外節點。
為什么多個 JSX 標簽需要被一個父元素包裹?
JSX 雖然看起來很像 HTML,但在底層其實被轉化為了 JavaScript 對象,你不能在一個函數中返回多個對象,除非用一個數組把他們包裝起來。這就是為什么多個 JSX 標簽必須要用一個父元素或者 Fragment 來包裹。
2. 標簽必須閉合
JSX 要求標簽必須正確閉合。像 <img>
這樣的自閉合標簽必須書寫成 <img />
,而像 <li>oranges
這樣只有開始標簽的元素必須帶有閉合標簽,需要改為 <li>oranges</li>
。
海蒂·拉瑪的照片和待辦事項的標簽經修改后變為:
<>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
/>
<ul>
<li>發明一種新式交通信號燈</li>
<li>排練一個電影場景</li>
<li>改進頻譜技術</li>
</ul>
</>
3. 使用駝峰式命名法給 大部分 屬性命名!
JSX 最終會被轉化為 JavaScript,而 JSX 中的屬性也會變成 JavaScript 對象中的鍵值對。在你自己的組件中,經常會遇到需要用變量的方式讀取這些屬性的時候。但 JavaScript 對變量的命名有限制。例如,變量名稱不能包含 -
符號或者像 class
這樣的保留字。
這就是為什么在 React 中,大部分 HTML 和 SVG 屬性都用駝峰式命名法表示。例如,需要用 strokeWidth
代替 stroke-width
。由于 class
是一個保留字,所以在 React 中需要用 className
來代替。這也是 DOM 屬性中的命名:
<img src="https://i.imgur.com/yXOvdOSs.jpg" alt="Hedy Lamarr" className="photo"/>
你可以 在 React DOM 元素中找到所有對應的屬性。如果你在編寫屬性時發生了錯誤,不用擔心 —— React 會在 瀏覽器控制臺 中打印一條可能的更正信息。
高級提示:使用 JSX 轉化器
將現有的 HTML 中的所有屬性轉化 JSX 的格式是很繁瑣的。我們建議使用 轉化器 將 HTML 和 SVG 標簽轉化為 JSX。這種轉化器在實踐中非常有用。但我們依然有必要去了解這種轉化過程中發生了什么,這樣你就可以編寫自己的 JSX 了。
這是最終的結果: