JSX 的全名是 JavaScript XML,為 JavaScript 提供一種類似 HTML 的擴充語法,JSX 讓開發者可以用比較簡潔的語法來建立 virtual DOM,但最終仍會被 babel 轉換為 JavaScript 語法,所以 JSX 只是語法糖(syntax)而不是全新的程式語言。
首先進入以下網址:https://codesandbox.io/s/new,就能進到由 CodeSandbox 提供的開發環境以及使用 create-react-app 指令建立好的 React 專案。
我們可以看到 index.js
這支檔案裡面的內容:
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
其中以下這一部分就是由 JSX 語法寫成的:
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
看起來和 HTML 語法沒什麼兩樣,若我們真的去建立一個 HTML 檔並且在裡面寫一樣的語法,也會得到幾乎如同畫面右方的結果。
實際上,JSX 語法會先經過 babel 轉譯成 JavaScript 程式碼,再經過瀏覽器執行,由 React 轉換為存在記憶體中的 virtual DOM 並且產生建立實際的 DOM。
以上面的 JSX 語法為例,丟到 online Babel compiler,就會轉換為:
React.createElement(
"div",
{
className: "App"
},
React.createElement(
"h1",
null,
"Hello CodeSandbox"
),
React.createElement(
"h2",
null,
"Start editing to see some magic happen!"
)
);
其中每一個呼叫 React.createElement() 都是在建立一個 Virtual DOM 中的節點。過去 React 開發者只能使用這種方式來建立 virtual DOM,一旦專案變得龐大,程式碼也會變得難以閱讀與維護,既然建立的 virtual DOM 最後會產生建立實際的 DOM,而 DOM 即是由 HTML 所組成,我們何不使用一種類似 HTML 的語法來開發呢?所以 react 才導入 JSX 語法來解決這個問題。
JSX 寫起來像 HTML,卻可以在其中加入 JavaScript 語法,看起來就像是 HTML 和 JavaScript 夾雜的晶晶體,這也是開發者一開始接觸 JSX 最不習慣的地方,其實只要掌握一些基本規則就能很快上手。
例如我們將 index.js
中 function 的部分改成如下:
function App() {
const who = 'CodeSandbox';
return (
<div className="App">
<h1>Hello {who}</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
JSX 會解析 {} 中的值,將 {who}
取代為 CodeSandbox
,所以畫面上可以看到和本來的畫面一樣的結果。我們可以把任何 JavaScript 運算式放進 {} 中,最後會呈現運算得到的結果,基本上能夠運算或解析得到值的都屬於 JavaScript 運算式,例如:1 + 2
、isValid && isSelected
、user.name
、add(a, b)
等等,但要注意若解析得到的值為布林值(true
或 false
)、null
、undefined
都會被忽略掉。
以下這些是等同的:
<div></div>
<div>{false}</div>
<div>{null}</div>
<div>{undefined}</div>
<div>{true}</div>
例如我們將 index.js
中 function 的部分改成如下:
function App() {
const title = <h1>Hello CodeSandbox</h1>;
return (
<div className="App">
{title}
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
由於 JSX 元素本身也是 JavaScript 運算式,所以它也可以賦值給變數,並且嵌入其他的 JSX 元素中。
若一個 JSX 元素中沒有內容:
<div></div>
我們也可以寫成:
<div />
若一個 JSX 元素本身沒有結尾標籤,例如
<input>
我們必須寫成:
<input />
大概介紹了 JSX 原理和基本規則,下一篇文章會更深入探討 JSX 的用法以及如何將 JSX 使用在一般屬性或是事件屬性上。
參考資料:
- Introducing JSX - https://reactjs.org/docs/introducing-jsx.html
- JSX In Depth - https://reactjs.org/docs/jsx-in-depth.html
- Expressions and operators - JavaScript | MDN - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators