react03 - 使用 JSX 書寫標(biāo)簽語(yǔ)言

JSX 是 JavaScript 語(yǔ)法擴(kuò)展,可以讓你在 JavaScript 文件中書寫類似 HTML 的標(biāo)簽。雖然還有其它方式可以編寫組件,但大部分 React 開(kāi)發(fā)者更喜歡 JSX 的簡(jiǎn)潔性,并且在大部分代碼庫(kù)中使用它。

你將會(huì)學(xué)習(xí)到:
· 為什么 React 將標(biāo)簽和渲染邏輯耦合在一起
· JSX 與 HTML 有什么區(qū)別
· 如何通過(guò) JSX 展示信息

JSX: 將標(biāo)簽引入 JavaScript

網(wǎng)頁(yè)是構(gòu)建在 HTML、CSS 和 JavaScript 之上的。多年以來(lái),web 開(kāi)發(fā)者都是將網(wǎng)頁(yè)內(nèi)容存放在 HTML 中,樣式放在 CSS 中,而邏輯則放在 JavaScript 中 —— 通常是在不同的文件中!頁(yè)面的內(nèi)容通過(guò)標(biāo)簽語(yǔ)言描述并存放在 HTML 文件中,而邏輯則單獨(dú)存放在 JavaScript 文件中。

但隨著 Web 的交互性越來(lái)越強(qiáng),邏輯越來(lái)越?jīng)Q定頁(yè)面中的內(nèi)容。JavaScript 控制著 HTML 的內(nèi)容!這也是為什么 在 React 中,渲染邏輯和標(biāo)簽共同存在于同一個(gè)地方——組件

將一個(gè)按鈕的渲染邏輯和標(biāo)簽放在一起可以確保它們?cè)诿看尉庉嫊r(shí)都能保持互相同步。反之,彼此無(wú)關(guān)的細(xì)節(jié)是互相隔離的,例如按鈕的標(biāo)簽和側(cè)邊欄的標(biāo)簽。這樣我們?cè)谛薷钠渲腥我庖粋€(gè)組件時(shí)會(huì)更安全。

每個(gè) React 組件都是一個(gè) JavaScript 函數(shù),它會(huì)返回一些標(biāo)簽,React 會(huì)將這些標(biāo)簽渲染到瀏覽器上。React 組件使用一種被稱為 JSX 的語(yǔ)法擴(kuò)展來(lái)描述這些標(biāo)簽。JSX 看起來(lái)和 HTML 很像,但它的語(yǔ)法更加嚴(yán)格并且可以動(dòng)態(tài)展示信息。了解這些區(qū)別最好的方式就是將一些 HTML 標(biāo)簽轉(zhuǎn)化為 JSX 標(biāo)簽。

JSX and React 是相互獨(dú)立的 東西。但它們經(jīng)常一起使用,但你 可以 單獨(dú)使用它們中的任意一個(gè),JSX 是一種語(yǔ)法擴(kuò)展,而 React 則是一個(gè) JavaScript 的庫(kù)。

將 HTML 轉(zhuǎn)化為 JSX

假設(shè)你現(xiàn)在有一些(完全有效的)HTML 標(biāo)簽:

<h1>海蒂·拉瑪?shù)拇k事項(xiàng)</h1>
<img 
  src="https://i.imgur.com/yXOvdOSs.jpg" 
  alt="Hedy Lamarr" 
  class="photo"
>
<ul>
    <li>發(fā)明一種新式交通信號(hào)燈
    <li>排練一個(gè)電影場(chǎng)景
    <li>改進(jìn)頻譜技術(shù)
</ul>

而現(xiàn)在想要把這些標(biāo)簽遷移到組件中:

export default function TodoList() {
  return (
    // ???
  )
}

如果直接復(fù)制到組件中,并不能正常工作:


這是因?yàn)?JSX 語(yǔ)法更加嚴(yán)格并且相比 HTML 有更多的規(guī)則!上面的錯(cuò)誤提示可以幫助你修復(fù)標(biāo)簽中的錯(cuò)誤,當(dāng)然也可以參考下面的指引。

大部分情況下,React 在屏幕上顯示的錯(cuò)誤提示就能幫你找到問(wèn)題所在,如果在編寫過(guò)程中遇到問(wèn)題就參考一下提示吧。

JSX 規(guī)則

1. 只能返回一個(gè)根元素

如果想要在一個(gè)組件中包含多個(gè)元素,需要用一個(gè)父標(biāo)簽把它們包裹起來(lái)。

例如,你可以使用一個(gè) <div> 標(biāo)簽:

<div>  
  <h1>海蒂·拉瑪?shù)拇k事項(xiàng)</h1>  
  <img     src="https://i.imgur.com/yXOvdOSs.jpg"     alt="Hedy Lamarr"     class="photo"  >  
  <ul>    ...  </ul>
</div>

如果你不想在標(biāo)簽中增加一個(gè)額外的 <div>,可以用 <></> 元素來(lái)代替:

<>  
  <h1>海蒂·拉瑪?shù)拇k事項(xiàng)</h1>  
  <img     src="https://i.imgur.com/yXOvdOSs.jpg"     alt="Hedy Lamarr"     class="photo"  >  
  <ul>    ...  </ul>
</>

這個(gè)空標(biāo)簽被稱作 Fragment。React Fragment 允許你將子元素分組,而不會(huì)在 HTML 結(jié)構(gòu)中添加額外節(jié)點(diǎn)。

為什么多個(gè) JSX 標(biāo)簽需要被一個(gè)父元素包裹?
JSX 雖然看起來(lái)很像 HTML,但在底層其實(shí)被轉(zhuǎn)化為了 JavaScript 對(duì)象,你不能在一個(gè)函數(shù)中返回多個(gè)對(duì)象,除非用一個(gè)數(shù)組把他們包裝起來(lái)。這就是為什么多個(gè) JSX 標(biāo)簽必須要用一個(gè)父元素或者 Fragment 來(lái)包裹。

2. 標(biāo)簽必須閉合

JSX 要求標(biāo)簽必須正確閉合。像 <img> 這樣的自閉合標(biāo)簽必須書寫成 <img />,而像 <li>oranges 這樣只有開(kāi)始標(biāo)簽的元素必須帶有閉合標(biāo)簽,需要改為 <li>oranges</li>。

海蒂·拉瑪?shù)恼掌痛k事項(xiàng)的標(biāo)簽經(jīng)修改后變?yōu)椋?/p>

<>
  <img 
    src="https://i.imgur.com/yXOvdOSs.jpg" 
    alt="Hedy Lamarr" 
    class="photo"
   />
  <ul>
      <li>發(fā)明一種新式交通信號(hào)燈</li>
      <li>排練一個(gè)電影場(chǎng)景</li>
      <li>改進(jìn)頻譜技術(shù)</li>
  </ul>
</>

3. 使用駝峰式命名法給 大部分 屬性命名!

JSX 最終會(huì)被轉(zhuǎn)化為 JavaScript,而 JSX 中的屬性也會(huì)變成 JavaScript 對(duì)象中的鍵值對(duì)。在你自己的組件中,經(jīng)常會(huì)遇到需要用變量的方式讀取這些屬性的時(shí)候。但 JavaScript 對(duì)變量的命名有限制。例如,變量名稱不能包含 - 符號(hào)或者像 class 這樣的保留字。

這就是為什么在 React 中,大部分 HTML 和 SVG 屬性都用駝峰式命名法表示。例如,需要用 strokeWidth 代替 stroke-width。由于 class 是一個(gè)保留字,所以在 React 中需要用 className 來(lái)代替。這也是 DOM 屬性中的命名:

<img   src="https://i.imgur.com/yXOvdOSs.jpg"   alt="Hedy Lamarr"   className="photo"/>

你可以 在 React DOM 元素中找到所有對(duì)應(yīng)的屬性。如果你在編寫屬性時(shí)發(fā)生了錯(cuò)誤,不用擔(dān)心 —— React 會(huì)在 瀏覽器控制臺(tái) 中打印一條可能的更正信息。

由于歷史原因,aria-*data-* 屬性是以帶 - 符號(hào)的 HTML 格式書寫的。

高級(jí)提示:使用 JSX 轉(zhuǎn)化器

將現(xiàn)有的 HTML 中的所有屬性轉(zhuǎn)化 JSX 的格式是很繁瑣的。我們建議使用 轉(zhuǎn)化器 將 HTML 和 SVG 標(biāo)簽轉(zhuǎn)化為 JSX。這種轉(zhuǎn)化器在實(shí)踐中非常有用。但我們依然有必要去了解這種轉(zhuǎn)化過(guò)程中發(fā)生了什么,這樣你就可以編寫自己的 JSX 了。

這是最終的結(jié)果:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容