# JSX
前面一直提到 JSX 語法,那么JSX到底是什么?
>[success] JSX是一種 JavaScript 的語法擴展,Javascript和XML結合的一種格式。React發明了JSX,利用HTML語法來創建虛擬DOM。當遇到<,JSX就當HTML解析,遇到{就當JavaScript解析。
## 使用JSX應該注意的幾點
第一, 在 JSX 中使用的“ 元素” 不局限于 HTML 中的 元素, 它可以是任何一個 React 組件,比如我們之前創建的 `Counter` 組件。
React 判斷 一個元素是 HTML 元素還是 React 組件的原則就是看第一個字母是否大寫, 如果在 JSX 中我們不用 `Counter` 而是用 `counter`, 那就得不到我們想要的結果。
第二, 在 JSX 中可以通過 `onClick` 這樣的方式給一個元素添加一個事件處理函數, 當然, 在 HTML 中也可以用 onclick( 注意和 `onClick` 拼寫有區別), 但在 HTML 中直接書寫 onclick 一直就是為人詬病的寫法, 網頁應用開發界一直倡導的是用 jQuery 的方法添加事件處理函數, 直接寫 onclick 會帶來代碼混亂的問題。
并不推薦在組件中直接使用 `onclick`,而是使用 `onClick`,主要是 `onclick` 有以下幾個缺點:
- onclick 添加的事件處理函數是在全局環境下執行的, 這污染了全局環境, 很容易產生意料不到的后果;
- 給很多 DOM 元素添加 onclick 事件, 可能會影響網頁的性能, 畢竟, 網頁需要的事件處理函數越多, 性能就會越低;
- 對于使用 onclick 的 DOM 元素, 如果要動態地從 DOM 樹中刪掉的話, 需要把對應的時間處理器注銷, 假如忘了注銷, 就可能造成 內存泄露, 這樣的 bug 很難被發現。
然而,在 JSX 中并不存在上述缺點。
在 JSX 中,使用 `onClick` 并不是將事件直接掛在到對應的 DOM 中,而是使用事件委托,掛在到DOM樹的最頂層中,這樣,無論添加多少個 `onClick` ,在DOM樹中都只有一個事件處理函數,再根據具體組件分派到不同的實現方法中。
(來自 [程墨. 深入淺出React和Redux (實戰) (Kindle位置276). 機械工業出版社. Kindle 版本. ](),有改動)
## 使用JSX
可以將任意DOM元素賦值到一個常量:
```jsx
const element = <h1>Hello, world!</h1>;
```
也可以創建一個嵌套的DOM樹
```jsx
const element = (
<div>
<h1>Hello!</h1>
<h2>Good to see you here.</h2>
</div>
);
```
JSX 乍看起來可能比較像是模版語言,但事實上它完全是在 JavaScript 內部實現的。
也可以在JSX中使用任意js表達式,在JSX中使用js表達式需要使用一對大括號 `{}`
```js
function formatName(user) {
return user.firstName + ' ' + user.lastName;
}
const user = {
firstName: 'Harper',
lastName: 'Perez'
};
const element = (
<h1>
Hello, {formatName(user)}!
</h1>
);
```
### JSX 本身其實也是一種表達式
在編譯之后,JSX 其實會被轉化為普通的 JavaScript 對象。
這就意味著,其實可以在 if 或者 for 語句里使用 JSX,將它賦值給變量,當作參數傳入,甚至作為函數返回值都可以:
```jsx
function getGreeting(user) {
if (user) {
return <h1>Hello, {formatName(user)}!</h1>;
}
return <h1>Hello, Stranger.</h1>;
}
```
### JSX 屬性
可以使用引號來定義以字符串為值的屬性
```jsx
const element = <div tabIndex="0"></div>;
```
可以使用大括號來定義以 JavaScript 表達式為值的屬性
```jsx
const user = {
avatarUrl: 'http://localhost/logo.png'
}
const element = <img src={user.avatarUrl} />;
```
切記在使用大括號包裹的 JavaScript 表達式時就不要再到外面套引號了。JSX 會將引號當中的內容識別為字符串而不是表達式。
>[warning] 因為 JSX 的特性更接近 JavaScript 而不是 HTML , 所以 React DOM 使用 camelCase 小駝峰命名 來定義屬性的名稱,而不是使用 HTML 的屬性名稱。
>例如,class 變成了 className,而 tabindex 則對應著 tabIndex.
### JSX只是一個語法糖
本質上來講,JSX 只是為 `React.createElement(component, props, ...children)` 方法提供的語法糖。
Babel 轉譯器會把 JSX 轉換成 React.createElement() 的方法調用。
所以,以下兩種寫法完全相同:
```jsx
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
```
```jsx
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
```
編譯后返回類似于以下結構的對象:
```jsx
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world'
}
};
```
- 簡介
- 第一章 React入門
- 1.1 創建一個React項目
- 1.2 組件
- 1.3 JSX
- 1.4 eject
- 1.5 渲染
- 第二章 React組件
- 2.1 組件定義
- 2.2 數據處理
- 2.2.1 props
- 2.2.2 state
- 2.3 生命周期
- 2.3.1 裝載過程
- 2.3.2 更新過程
- 2.3.3 卸載過程
- 2.4 事件處理
- 2.5 條件渲染
- 2.6 列表渲染
- 第三章 React高級
- 3.1 靜態類型檢查
- 3.1.1 flow
- 3.1.2 typescript
- 3.2 React Developer Tools
- 第四章 Redux狀態管理
- 4.1 安裝與配置
- 4.2 一個簡單的計數器開始
- 4.3 Store
- 4.3.1 獲取state
- 4.3.2 subscribe
- 4.4 Action
- 4.4.1 Action Creators
- 4.5 Reducer
- 4.5.1 Reducer 的拆分
- 4.6 與其他狀態管理工具的對比
- 第五章 React-Router路由
- 參考資料