什麼是虛拟DOM
用js對象的形式,來表示DOM和DOM之間的嵌套關系。
參數1
建立的元素的類型, 字元串,表示元素的名稱
參數2
一個對象或 null,表示目前這個DOM元素的屬性
參數3
子節點(包括其它虛拟DOM擷取文本子節點)
參數
其它子節點
但如果元素很多,這樣寫就很不好呢,每次都要建立元素的 API。
畢竟頁面上本質都是各種 html 标簽,還是直接手寫各種标簽最簡單暴力。
但是HTML是标記語言。JS檔案預設不能寫這種HTML标記,打包會失敗,使用 babel 來轉換這些JS中的标簽即可!
這種在JS中,混合寫入類似于HTML的文法,叫做JSX。
符合 XML規範的JS。JSX 文法的本質,還是在運作的時候,被轉換成了React. createElement形式執行。
引入JSX
添加支援

插件支援
引入依賴
React提供的環境搭建工具示範
配置檔案可讀性差,是以不考慮使用這種現成方式寫項目,跳過。
觀察一下聲明的這個變量:
這種看起來可能有些奇怪的标簽文法既不是js 文法也不是 HTML文法,而是能在 js 中使用 html 标簽,這被稱為 JSX, 一種 JavaScript 的文法擴充。
推薦在 React 中使用 JSX 來描述使用者界面。JSX 乍看起來可能比較像是模版語言,但事實上它完全是在 JavaScript 内部實作的。
JSX 用來聲明 React 當中的元素。
JSX 的基本使用方法
可任意地在 JSX 當中使用 JavaScript 表達式,在 JSX 當中的表達式要包含在大括号裡
例如 <code>2 + 2</code>, <code>user.firstName</code>, 以及 <code>formatName(user)</code> 都是可以使用的
在 CodePen 上試試
書寫 JSX 的時候一般都會帶上換行和縮進,這樣可以增強代碼的可讀性
同樣推薦在 JSX 代碼的外面擴上一個小括号,這樣可以防止 分号自動插入 的 bug
在編譯後,JSX 其實會被轉化為普通的 JavaScript 對象
這意味着,你其實可以在 if 或者 for 語句裡使用 JSX,将它指派給變量,當作參數傳入,作為傳回值都可以
JSX 屬性
切記你使用了{}包裹的 js 表達式時就不要再到外面套引号了。
<code>JSX 會将引号當中的内容識别為字元串而非表達式</code>!
React 中需要把 key 添加給 forEach 或 map 或 for 循環直接控制的元素
JSX 嵌套
若 JSX 标簽是閉合式的,需在結尾處用<code>/></code>, 就好像 XML/HTML 一樣
JSX 标簽同樣可以互相嵌套
警告: 因為 JSX 的特性更接近 JavaScript 而不是 HTML , 是以 React DOM 使用 <code>camelCase</code> 小駝峰命名 來定義屬性的名稱,而不是使用 HTML 的屬性名稱 如 <code>class</code> 變成了 <code>className</code> 而 <code>tabindex</code> 則對應着 <code>tabIndex</code>
JSX 防注入攻擊
可放心在 JSX 當中使用使用者輸入
React DOM 在渲染之前預設會 過濾 所有傳入的值
它可以確定你的應用不會被注入攻擊。所有的内容在渲染之前都被轉換成了字元串。這樣可以有效地防止 XSS(跨站腳本) 攻擊
JSX 代表 Objects
Babel 轉譯器會把 JSX 轉換成一個名為 <code>React.createElement()</code>的方法調用
下面兩種代碼的作用是完全相同的
<code>React.createElement()</code>首先會進行一些避免bug的檢查,之後會傳回一個類似下面例子的對象
這樣的對象被稱為 “React 元素”。它代表所有你在螢幕上看到的東西。React 通過讀取這些對象來建構 DOM 并保持資料内容一緻。
JSX 的怪異之處
React 元件隻能渲染一個根節點。為啥呢?先來看看render函數的一個傳回示例:
它會被轉換成一條語句:
<code>return React.createElement("h1",null,"Hello World");</code>
但面的代碼卻不是合法的:
這并非JSX 的限制,而是JavaScript 的一個特性:一條傳回語句隻能傳回單個值,而我們嘗試傳回兩條語句(兩次React.createElement 調用)。
解決的方法非常簡單:就像你在普通JavaScript 中會做的那樣,将所有傳回值包含到一個根對象
它完全有效,因為它會被轉換成:
它傳回單個值,并且是通過合法的JavaScript 完成的。
條件語句
如果語句不相容于JSX,看上去像是JSX 的限制所緻,實際上卻是因為JSX 隻是普通的JavaScript
回顧一下JSX 是如何被轉換為普通JavaScript
如下JSX
會被轉換成這樣的JavaScript
然而,如果嘗試在JSX 的中間編寫if 語句,例如:
<code><div className={if (condition) { "salutation" }}>Hello JSX</div></code>
它就會被轉換成一個非法的JavaScript 表達式,如圖2-1 所示:
有什麼解決方法?
盡管并無可能在JSX 中使用“if”語句,但仍有根據條件渲染内容的方法,包括使用三元表達式和将條件指派給一個變量(空值和未定義的值都會被React 進行處理,JSX在轉義時什麼都不會輸出)。
使用三元表達式
如果你有一個非常簡單的表達式,可以使用三元形式:
這段代碼會被轉換成一段合法的JavaScript:
三元形式還可用來有條件地渲染整個節點:
将條件外置
如果三元表達式還不能應付你的要求,解決方法是不要在JSX 的中間使用條件。簡單地将條件語句移動到外部(就像你在第2 章中隐藏和顯示ContactItem 細節時所采取的方法)。
下面是原先的代碼:
将條件移動到JSX 的外部,就像:
React 知道如何處理未定義的值,如果條件為假,它甚至不會在div 标簽中建立class特性。