iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 10
0
Modern Web

使用 React 製作簡易專案管理網站:從基礎到實戰系列 第 10

[Day 10] React 保衛戰 - 別怕!JSX 不過是個語法糖!而且還是個晶晶體?!

  • 分享至 

  • xImage
  •  

什麼是 JSX ?

JSX 的全名是 JavaScript XML,為 JavaScript 提供一種類似 HTML 的擴充語法,JSX 讓開發者可以用比較簡潔的語法來建立 virtual DOM,但最終仍會被 babel 轉換為 JavaScript 語法,所以 JSX 只是語法糖(syntax)而不是全新的程式語言。

外表看似 HTML 的 JSX - JSX 原理

首先進入以下網址:https://codesandbox.io/s/new,就能進到由 CodeSandbox 提供的開發環境以及使用 create-react-app 指令建立好的 React 專案。

https://ithelp.ithome.com.tw/upload/images/20190925/20104727yVMzWcKw7e.png

我們可以看到 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。

https://ithelp.ithome.com.tw/upload/images/20190926/20104727aU4KjQSdu5.png

以上面的 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 就是一種晶晶體 - JSX 基本規則

JSX 寫起來像 HTML,卻可以在其中加入 JavaScript 語法,看起來就像是 HTML 和 JavaScript 夾雜的晶晶體,這也是開發者一開始接觸 JSX 最不習慣的地方,其實只要掌握一些基本規則就能很快上手。

JSX 元素內容可以嵌入 JavaScript 運算式

例如我們將 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 + 2isValid && isSelecteduser.nameadd(a, b) 等等,但要注意若解析得到的值為布林值(truefalse)、nullundefined 都會被忽略掉。

以下這些是等同的:

<div></div>

<div>{false}</div>

<div>{null}</div>

<div>{undefined}</div>

<div>{true}</div>

JSX 元素本身也是 JavaScript 運算式

例如我們將 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 元素可以自閉

若一個 JSX 元素中沒有內容:

<div></div>

我們也可以寫成:

<div />

沒有結尾標籤的 JSX 元素必須自閉

若一個 JSX 元素本身沒有結尾標籤,例如

<input>

我們必須寫成:

<input />

結語

大概介紹了 JSX 原理和基本規則,下一篇文章會更深入探討 JSX 的用法以及如何將 JSX 使用在一般屬性或是事件屬性上。

參考資料:

  1. Introducing JSX - https://reactjs.org/docs/introducing-jsx.html
  2. JSX In Depth - https://reactjs.org/docs/jsx-in-depth.html
  3. Expressions and operators - JavaScript | MDN - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators

上一篇
[Day 9] ES6 前哨戰 - import/export
下一篇
[Day 11] React 保衛戰 - 注意!JSX 元素屬性是 HTML 元素屬性的變形
系列文
使用 React 製作簡易專案管理網站:從基礎到實戰30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言