2-2 把 HTML 寫在 JavaScript 中!? - JSX 的概念

在前一個單元中我們完成了一個簡單的計時器頁面,感覺用原生的 JavaScript 來寫計數器並不會太過複雜,我們只需要在特定的 HTML 元素上使用 addEventListener 去監聽事件,再透過 textContent 去修改元素內的文字內容就可以了。這麼說起來,我們為什麼需要透過 JSX 去把 HTML 寫在 JavaScript 內呢?

為什麼需要 JSX#

以前 Nokia 的有一句經典的話,叫做「科技始終來自於人性」。

這句話同樣適合用在前端技術的演進上,多數新技術的推出都是因為在當時有新的需求或需要解決的問題,事後學習這些技術的我們,可能不會知道當時的人為什麼要用這種寫法或使用這類工具,所以如果你在學習的過程中,對這些新技術或工具感到困惑的話,不妨可以試著去查查這些工具或方法當時想要解決的是什麼問題,在學習上比較不會那麼納悶為什麼有這麼多看起來有的沒的東西

雖然昨天透過 JavaScript 來修改網頁內容的做法看起來並不會太複雜,但這是因為現在我們只需要改變網頁上的一個內容(即,計數器的數字),假設現在網頁上有非常多的內容是需要透過 JavaScript 來替換的話,這個動作會變得非常繁瑣。舉例來說,在 iThome 的個人資料裡有許多不同的欄位,包括「帳號名稱」、「累積瀏覽數」、「追蹤數」、「發問次數」、「文章發布數」、....。

imgur

假設這些資料不是一開始就透過網頁伺服器產生好,而是透過 AJAX 向後端拉取資料後才要放進去網頁時,要把這些欄位一個一個換掉就會變得相當麻煩,需要先一個又一個選到該 HTML 元素,再一個又一個把它們換掉。

透過 JSX 等於我們可以直接把 HTML 放到 JavaScript 中去操作,不再需要先用 querySelector 去選到該元素後才能換掉,而是可以在 HTML 中直接帶入 JavaScript 的變數

除此之外,如果現在希望某個使用者的「最佳解答」超過一定數目就在個人資料中額外出現一個獎勵標章時,透過 JSX 這種把 HTML 寫在 JavaScript 中的方式,就可以直接使用 if 判斷式。它的好處還不只這些,後面我們會再逐一提到,讓我們先來看看如何用 JSX 寫一個超簡單的 Hello World 吧!

簡單的說,在 JSX 的加持之下,讓開發者可以把 JavaScript 內的用法與程式邏輯,直接套用到 HTML 的元素上,就是一個「強化版 HTML 」的概念!

用 JSX 寫 Hello World#

再把原本的計數器改成 JSX 的寫法之前,我們先來看一個非常簡單的 JSX 範例,這是 React 官方提供的 Hello World 樣板。請你在 Github 說明頁點擊「React Hello World 樣板」的連結,或打開下面這個 CodePen 連結:

Imgur

https://codepen.io/PJCHENder/pen/bGbMQQw

imgur

內容很精簡,在 HTML 的部分就是單純的一個 <div> 而已:

<div id="root"></div>

在 JavaScript 的地方則是使用了 ReactDOM.render 這個語法,在 ReactDOM.render() 的第一個參數放的就是 JSX 的內容,這裡看起來其實就和直接放入 HTML 一樣;第二個參數則是說明這個 JSX 的內容要被放到原本 HTML 中的哪個位置內,這裡就是放到 id 為 root 的這個元素上,因此使用 document.getElementById('root') 選到這個元素:

// JavaScript
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);

所以最後出來的畫面就會是:

imgur

可以在 <div id="root"> 的元素中看到寫在 JavaScript 中 JSX 的內容。

什麼是 JSX#

相信許多人一開始聽到學 React 之前要先學 JSX 就望之卻步,默默想說那還是以後再來看好了...。但現在回頭來看什麼是 JSX,以上面的例子來說,這個部分就是 JSX:

imgur

你可能好奇,阿這不就只是 HTML 嗎?

沒錯,JSX 簡單來說,就是把你已經知道的 HTML 放到 JavaScript 內,但同時因為它被放在 JavaScript 中,所以可以使用 JavaScript 中提供的各種語法,例如之後我們會在 JSX 這裡面放入 JavaScript 的變數、執行條件判斷式、進行迴圈等等。你可以把 JSX 看成是一個增強版的 HTML,讓我們可以用更簡便的方法對 HTML 進行修改和操作

簡單的說,在 JSX 的加持之下,開發者可以把 JavaScript 內的用法與程式邏輯,直接套用到 HTML 的元素上,就是一個「強化版 HTML 」的概念!

記得載入 React 和 ReactDOM 套件#

這裡你可能會好奇,為什麼可以直接在 JavaScript 中使用 ReactDOM.render 這個方法,而且可以直接在裡面就開始撰寫 JSX 呢?這是因為,在剛剛 React 提供的這個「Hello World 樣板」中,已經幫我們在 CodePen 中載入所需的套件了,你可以點選 JavaScript 側邊欄中的齒輪後:

imgur

在點開齒輪來看之前,看到有使用了名為 Babel 的 JavaScript 前處理器(Preprocessor),主要是因為 JavaScript 這幾年更新的非常快速,有些最新的語法部分瀏覽器可能尚未支援,而 Babel 就是用來讓最新的 JavaScript 語法可以支援在不同版本的瀏覽器上運行。

note

💡 Tips:Babel 有另外提供名為 @babel/standalone 的套件,讓開發者也可以在網頁中透過 <script> 直接載入 Babel 使用,但一般來說,正式產品開發時還是會在電腦上透過 Babel 把 JavaScript 程式碼進行編譯處理,而不是等到使用者瀏覽到該頁面時才做編譯的動作。

接著點開齒輪後,看到這個 Hello World 樣板中,已經預先載入兩個 JavaScript 套件,分別是 ReactReactDOM 這兩個套件。其中 React 這個套件就可去解讀 JSX 的內容,而 ReactDOM 則可以讓所撰寫的內容,放置到特定 HTML DOM 中的元素上。

imgur

也就是因為這裡有預先載入了 React 和 ReactDOM 這兩個套件,所以我們的 JSX 才能被正確解析,才能把 HTML 放到 JavaScript 中使用。

前面我們有提到,JSX 就像是威力加強版的 HTML,因此勢必會提供我們更多實用的功能,在後面的單元中,我們會再陸續看到可以怎麼運用 JSX 來增加許多單純用 HTML 做不到的功能。